[-]
[+]
|
Changed |
_service
|
@@ -3,5 +3,5 @@
- <param name="protocol">http</param><param name="host">haproxy.1wt.eu</param><param name="path">/download/1.5/src/haproxy-1.5.11.tar.gz</param></service>
+ <param name="protocol">http</param><param name="host">haproxy.1wt.eu</param><param name="path">/download/1.5/src/haproxy-1.5.12.tar.gz</param></service>
</services>
\ No newline at end of file
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/CHANGELOG
^
|
@@ -1,6 +1,38 @@
ChangeLog :
===========
+2015/05/02 : 1.5.12
+ - BUG/MINOR: ssl: Display correct filename in error message
+ - DOC: Fix L4TOUT typo in documentation
+ - BUG/MEDIUM: Do not consider an agent check as failed on L7 error
+ - BUG/MINOR: pattern: error message missing
+ - BUG/MEDIUM: pattern: some entries are not deleted with case insensitive match
+ - BUG/MEDIUM: buffer: one byte miss in buffer free space check
+ - BUG/MAJOR: http: don't read past buffer's end in http_replace_value
+ - BUG/MEDIUM: http: the function "(req|res)-replace-value" doesn't respect the HTTP syntax
+ - BUG/MEDIUM: peers: correctly configure the client timeout
+ - BUG/MINOR: compression: consider the expansion factor in init
+ - BUG/MEDIUM: http: hdr_cnt would not count any header when called without name
+ - BUG/MEDIUM: listener: don't report an error when resuming unbound listeners
+ - BUG/MEDIUM: init: don't limit cpu-map to the first 32 processes only
+ - BUG/MEDIUM: stream-int: always reset si->ops when si->end is nullified
+ - BUG/MEDIUM: http: remove content-length from chunked messages
+ - DOC: http: update the comments about the rules for determining transfer-length
+ - BUG/MEDIUM: http: do not restrict parsing of transfer-encoding to HTTP/1.1
+ - BUG/MEDIUM: http: incorrect transfer-coding in the request is a bad request
+ - BUG/MEDIUM: http: remove content-length form responses with bad transfer-encoding
+ - MEDIUM: http: restrict the HTTP version token to 1 digit as per RFC7230
+ - MEDIUM: http: add option-ignore-probes to get rid of the floods of 408
+ - BUG/MINOR: config: clear proxy->table.peers.p for disabled proxies
+ - MINOR: stick-table: don't attach to peers in stopped state
+ - MEDIUM: config: initialize stick-tables after peers, not before
+ - MEDIUM: peers: add the ability to disable a peers section
+ - DOC: document option http-ignore-probes
+ - DOC: fix the comments about the meaning of msg->sol in HTTP
+ - BUG/MEDIUM: http: wait for the exact amount of body bytes in wait_for_request_body
+ - BUG/MAJOR: http: prevent risk of reading past end with balance url_param
+ - DOC: update the doc on the proxy protocol
+
2015/02/01 : 1.5.11
- BUG/MEDIUM: backend: correctly detect the domain when use_domain_only is used
- MINOR: ssl: load certificates in alphabetical order
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/README
^
|
@@ -1,9 +1,9 @@
----------------------
HAProxy how-to
----------------------
- version 1.5.11
+ version 1.5.12
willy tarreau
- 2015/02/01
+ 2015/05/02
1) How to build it
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/VERDATE
^
|
@@ -1,2 +1,2 @@
$Format:%ci$
-2015/01/31
+2015/05/02
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/VERSION
^
|
@@ -1 +1 @@
-1.5.11
+1.5.12
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/doc/configuration.txt
^
|
@@ -2,9 +2,9 @@
HAProxy
Configuration Manual
----------------------
- version 1.5.11
+ version 1.5.12
willy tarreau
- 2015/02/01
+ 2015/05/02
This document covers the configuration language as implemented in the version
@@ -1148,6 +1148,14 @@
Creates a new peer list with name <peersect>. It is an independent section,
which is referenced by one or more stick-tables.
+disabled
+ Disables a peers section. It disables both listening and any synchronization
+ related to this section. This is provided to disable synchronization of stick
+ tables without having to comment out all "peers" references.
+
+enable
+ This re-enables a disabled peers section which was previously disabled.
+
peer <peername> <ip>:<port>
Defines a peer inside a peers section.
If <peername> is set to the local peer name (by default hostname, or forced
@@ -1342,6 +1350,7 @@
option forceclose (*) X X X X
-- keyword -------------------------- defaults - frontend - listen -- backend -
option forwardfor X X X X
+option http-ignore-probes (*) X X X -
option http-keep-alive (*) X X X X
option http-no-delay (*) X X X X
option http-pretend-keepalive (*) X X X X
@@ -3747,7 +3756,7 @@
yes | yes | yes | no
Arguments : none
- By default, HAProxy complies with RFC2616 in terms of message parsing. This
+ By default, HAProxy complies with RFC7230 in terms of message parsing. This
means that invalid characters in header names are not permitted and cause an
error to be returned to the client. This is the desired behaviour as such
forbidden characters are essentially used to build attacks exploiting server
@@ -3760,7 +3769,9 @@
chars 0-31, 32 (space), 34 ('"'), 60 ('<'), 62 ('>'), 92 ('\'), 94 ('^'), 96
('`'), 123 ('{'), 124 ('|'), 125 ('}'), 127 (delete) and anything above are
not allowed at all. Haproxy always blocks a number of them (0..32, 127). The
- remaining ones are blocked by default unless this option is enabled.
+ remaining ones are blocked by default unless this option is enabled. This
+ option also relaxes the test on the HTTP version format, it allows multiple
+ digits for both the major and the minor version.
This option should never be enabled by default as it hides application bugs
and open security breaches. It should only be deployed after a problem has
@@ -3786,7 +3797,7 @@
yes | no | yes | yes
Arguments : none
- By default, HAProxy complies with RFC2616 in terms of message parsing. This
+ By default, HAProxy complies with RFC7230 in terms of message parsing. This
means that invalid characters in header names are not permitted and cause an
error to be returned to the client. This is the desired behaviour as such
forbidden characters are essentially used to build attacks exploiting server
@@ -3794,7 +3805,9 @@
server will emit invalid header names for whatever reason (configuration,
implementation) and the issue will not be immediately fixed. In such a case,
it is possible to relax HAProxy's header name parser to accept any character
- even if that does not make sense, by specifying this option.
+ even if that does not make sense, by specifying this option. This option also
+ relaxes the test on the HTTP version format, it allows multiple digits for
+ both the major and the minor version.
This option should never be enabled by default as it hides application bugs
and open security breaches. It should only be deployed after a problem has
@@ -3970,7 +3983,9 @@
simple port probe or scan will produce a log. If those connections pollute
the logs too much, it is possible to enable option "dontlognull" to indicate
that a connection on which no data has been transferred will not be logged,
- which typically corresponds to those probes.
+ which typically corresponds to those probes. Note that errors will still be
+ returned to the client and accounted for in the stats. If this is not what is
+ desired, option http-ignore-probes can be used instead.
It is generally recommended not to use this option in uncontrolled
environments (eg: internet), otherwise scans and other malicious activities
@@ -3979,7 +3994,8 @@
If this option has been enabled in a "defaults" section, it can be disabled
in a specific instance by prepending the "no" keyword before it.
- See also : "log", "monitor-net", "monitor-uri" and section 8 about logging.
+ See also : "log", "http-ignore-probes", "monitor-net", "monitor-uri", and
+ section 8 about logging.
option forceclose
@@ -4075,6 +4091,40 @@
"option forceclose", "option http-keep-alive"
+option http-ignore-probes
+no option http-ignore-probes
+ Enable or disable logging of null connections and request timeouts
+ May be used in sections : defaults | frontend | listen | backend
+ yes | yes | yes | no
+ Arguments : none
+
+ Recently some browsers started to implement a "pre-connect" feature
+ consisting in speculatively connecting to some recently visited web sites
+ just in case the user would like to visit them. This results in many
+ connections being established to web sites, which end up in 408 Request
+ Timeout if the timeout strikes first, or 400 Bad Request when the browser
+ decides to close them first. These ones pollute the log and feed the error
+ counters. There was already "option dontlognull" but it's insufficient in
+ this case. Instead, this option does the following things :
+ - prevent any 400/408 message from being sent to the client if nothing
+ was received over a connection before it was closed ;
+ - prevent any log from being emitted in this situation ;
+ - prevent any error counter from being incremented
+
+ That way the empty connection is silently ignored. Note that it is better
+ not to use this unless it is clear that it is needed, because it will hide
+ real problems. The most common reason for not receiving a request and seeing
+ a 408 is due to an MTU inconsistency between the client and an intermediary
+ element such as a VPN, which blocks too large packets. These issues are
+ generally seen with POST requests as well as GET with large cookies. The logs
+ are often the only way to detect them.
+
+ If this option has been enabled in a "defaults" section, it can be disabled
+ in a specific instance by prepending the "no" keyword before it.
+
+ See also : "log", "dontlognull", "errorfile", and section 8 about logging.
+
+
option http-keep-alive
no option http-keep-alive
Enable or disable HTTP keep-alive from client to server
@@ -7868,8 +7918,8 @@
about the problem, and the connection is closed. The logs will report
termination codes "cR". Some recent browsers are having problems with this
standard, well-documented behaviour, so it might be needed to hide the 408
- code using "errorfile 408 /dev/null". See more details in the explanations of
- the "cR" termination code in section 8.5.
+ code using "option http-ignore-probes" or "errorfile 408 /dev/null". See
+ more details in the explanations of the "cR" termination code in section 8.5.
Note that this timeout only applies to the header part of the request, and
not to any data. As soon as the empty line is received, this timeout is not
@@ -7887,7 +7937,8 @@
effect, unless the frontend is in TCP mode, in which case the HTTP backend's
timeout will be used.
- See also : "errorfile", "timeout http-keep-alive", "timeout client".
+ See also : "errorfile", "http-ignore-probes", "timeout http-keep-alive", and
+ "timeout client".
timeout queue <timeout>
@@ -12765,7 +12816,8 @@
the request was typed by hand using a telnet client, and aborted
too early. The HTTP status code is likely a 400 here. Sometimes this
might also be caused by an IDS killing the connection between haproxy
- and the client.
+ and the client. "option http-ignore-probes" can be used to ignore
+ connections without any data transfer.
cR The "timeout http-request" stroke before the client sent a full HTTP
request. This is sometimes caused by too large TCP MSS values on the
@@ -12773,19 +12825,18 @@
packets, or by clients sending requests by hand and not typing fast
enough, or forgetting to enter the empty line at the end of the
request. The HTTP status code is likely a 408 here. Note: recently,
- some browsers such as Google Chrome started to break the deployed Web
- infrastructure by aggressively implementing a new "pre-connect"
- feature, consisting in sending connections to sites recently visited
- without sending any request on them until the user starts to browse
- the site. This mechanism causes massive disruption among resource-
- limited servers, and causes a lot of 408 errors in HAProxy logs.
- Worse, some people report that sometimes the browser displays the 408
- error when the user expects to see the actual content (Mozilla fixed
- this bug in 2004, while Chrome users continue to report it in 2014),
- so in this case, using "errorfile 408 /dev/null" can be used as a
- workaround. More information on the subject is available here :
- https://bugzilla.mozilla.org/show_bug.cgi?id=248827
- https://code.google.com/p/chromium/issues/detail?id=85229
+ some browsers started to implement a "pre-connect" feature consisting
+ in speculatively connecting to some recently visited web sites just
+ in case the user would like to visit them. This results in many
+ connections being established to web sites, which end up in 408
+ Request Timeout if the timeout strikes first, or 400 Bad Request when
+ the browser decides to close them first. These ones pollute the log
+ and feed the error counters. Some versions of some browsers have even
+ been reported to display the error code. It is possible to work
+ around the undesirable effects of this behaviour by adding "option
+ http-ignore-probes" in the frontend, resulting in connections with
+ zero data transfer to be totally ignored. This will definitely hide
+ the errors of people experiencing connectivity issues though.
CT The client aborted while its session was tarpitted. It is important to
check if this happens on valid requests, in order to be sure that no
@@ -13220,7 +13271,7 @@
INI -> initializing
SOCKERR -> socket error
L4OK -> check passed on layer 4, no upper layers testing enabled
- L4TMOUT -> layer 1-4 timeout
+ L4TOUT -> layer 1-4 timeout
L4CON -> layer 1-4 connection problem, for example
"Connection refused" (tcp rst) or "No route to host" (icmp)
L6OK -> check passed on layer 6
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/doc/proxy-protocol.txt
^
|
@@ -1,4 +1,4 @@
-2014/07/25 Willy Tarreau
+2015/05/02 Willy Tarreau
HAProxy Technologies
The PROXY protocol
Versions 1 & 2
@@ -22,6 +22,7 @@
2014/06/11 - fix example code to consider ver+cmd merge
2014/06/14 - fix v2 header check in example code, and update Forwarded spec
2014/07/12 - update list of implementations (add Squid)
+ 2015/05/02 - update list of implementations and format of the TLV add-ons
1. Background
@@ -515,12 +516,54 @@
the Type and Length bytes), and following the length field is the number of
bytes specified by the length.
- struct {
+ struct pp2_tlv {
uint8_t type;
uint8_t length_hi;
uint8_t length_lo;
uint8_t value[0];
- } tlv;
+ };
+
+The following types have already been registered for the <type> field :
+
+ #define PP2_TYPE_ALPN 0x01
+ #define PP2_TYPE_AUTHORITY 0x02
+ #define PP2_TYPE_SSL 0x20
+ #define PP2_TYPE_SSL_VERSION 0x21
+ #define PP2_TYPE_SSL_CN 0x22
+ #define PP2_TYPE_NETNS 0x30
+
+For the type PP2_TYPE_SSL, the value is itselv a defined like this :
+
+ struct pp2_tlv_ssl {
+ uint8_t client;
+ uint32_t verify;
+ struct pp2_tlv sub_tlv[0];
+ };
+
+And the <client> field is made of a bit field from the following values,
+indicating which element is present :
+
+ #define PP2_CLIENT_SSL 0x01
+ #define PP2_CLIENT_CERT_CONN 0x02
+ #define PP2_CLIENT_CERT_SESS 0x04
+
+Each of these elements may lead to extra data being appended to this TLV using
+a second level of TLV encapsulation. It is thus possible to find multiple TLV
+values after this field. The total length of the upper TLV will reflect this.
+
+PP2_CLIENT_SSL indicates that the client connected over SSL/TLS. When this
+field is present, the string representation of the TLS version is appended at
+the end of the field in the TLV format using the type PP2_TYPE_SSL_VERSION.
+
+PP2_CLIENT_CERT_CONN indicates that the client provided a certificate over the
+current connection. PP2_CLIENT_CERT_SESS indicates that the client provided a
+certificate at least once over the TLS session this connection belongs to. In
+both cases, the string representation of the client certificate's CN may be
+appended after the SSL/TLS version using the TLV format using the type
+PP2_TYPE_SSL_CN.
+
+The type PP2_TYPE_NETNS defines the value as the string representation of the
+namespace's name.
3. Implementations
@@ -554,11 +597,15 @@
A patch is available for Stud[5] to implement version 1 of the protocol on
incoming connections.
-Support for the protocol in the Varnish cache is being considered [6].
+Support for versions 1 and 2 of the protocol was added to Varnish 4.1 [6].
Exim added support for version 1 and version 2 of the protocol for incoming
connections on 2014/05/13, and will be released as part of version 4.83.
+Squid added support for versions 1 and 2 of the protocol in version 3.5 [7].
+
+Jetty 9.3.0 supports protocol version 1.
+
The protocol is simple enough that it is expected that other implementations
will appear, especially in environments such as SMTP, IMAP, FTP, RDP where the
client's address is an important piece of information for the server and some
@@ -743,7 +790,8 @@
[3] http://www.stunnel.org/
[4] https://github.com/bumptech/stud
[5] https://github.com/bumptech/stud/pull/81
-[6] https://www.varnish-cache.org/trac/wiki/Future_Protocols
+[6] https://www.varnish-cache.org/docs/trunk/phk/ssl_again.html
+[7] http://wiki.squid-cache.org/Squid-3.5
9. Sample code
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/examples/haproxy.spec
^
|
@@ -1,6 +1,6 @@
Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability environments
Name: haproxy
-Version: 1.5.11
+Version: 1.5.12
Release: 1
License: GPL
Group: System Environment/Daemons
@@ -76,6 +76,9 @@
%attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
%changelog
+* Sat May 2 2015 Willy Tarreau <w@1wt.eu>
+- updated to 1.5.12
+
* Sun Feb 1 2015 Willy Tarreau <w@1wt.eu>
- updated to 1.5.11
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/include/proto/stream_interface.h
^
|
@@ -99,6 +99,7 @@
si->flags = SI_FL_NONE;
si->end = NULL;
si->state = si->prev_state = SI_ST_INI;
+ si->ops = &si_embedded_ops;
}
/* sets the current and previous state of a stream interface to <state>. This
@@ -131,12 +132,12 @@
appctx_free(appctx); /* we share the connection pool */
}
si->end = NULL;
+ si->ops = &si_embedded_ops;
}
static inline void si_detach(struct stream_interface *si)
{
si_release_endpoint(si);
- si->ops = &si_embedded_ops;
}
/* Turn a possibly existing connection endpoint of stream interface <si> to
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/include/types/proto_http.h
^
|
@@ -352,7 +352,11 @@
* - next (parse pointer) : next relative byte to be parsed. Always points
* to a byte matching the current state.
*
- * - sol (start of line) : start of current line before MSG_BODY, or zero.
+ * - sol (start of line) : start of current line before MSG_BODY. Starting
+ * from MSG_BODY, contains the length of the last
+ * parsed chunk size so that when added to sov it
+ * always points to the beginning of the current
+ * data chunk.
*
* - eol (End of Line) : Before HTTP_MSG_BODY, relative offset in the
* buffer of the first byte which marks the end of
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/include/types/proxy.h
^
|
@@ -82,7 +82,7 @@
#define PR_O_DISPATCH 0x00000040 /* use dispatch mode */
/* unused: 0x00000080 */
#define PR_O_FWDFOR 0x00000100 /* conditionally insert x-forwarded-for with client address */
-/* unused: 0x00000200 */
+#define PR_O_IGNORE_PRB 0x00000200 /* ignore empty requests (aborts and timeouts) */
#define PR_O_NULLNOLOG 0x00000400 /* a connect without request will not be logged */
/* unused: 0x0800, 0x1000 */
#define PR_O_FF_ALWAYS 0x00002000 /* always set x-forwarded-for */
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/backend.c
^
|
@@ -309,6 +309,9 @@
if (len == 0)
return NULL;
+ if (len > req->buf->data + req->buf->size - p)
+ len = req->buf->data + req->buf->size - p;
+
if (px->lbprm.tot_weight == 0)
return NULL;
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/buffer.c
^
|
@@ -46,7 +46,7 @@
delta = len - (end - pos);
- if (bi_end(b) + delta >= b->data + b->size)
+ if (bi_end(b) + delta > b->data + b->size)
return 0; /* no space left */
if (buffer_not_empty(b) &&
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/cfgparse.c
^
|
@@ -151,6 +151,7 @@
{ "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0, 0 },
{ "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0, 0 },
{ "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
+ { "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
{ "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
{ "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
{ "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
@@ -1743,6 +1744,7 @@
curpeers->conf.line = linenum;
curpeers->last_change = now.tv_sec;
curpeers->id = strdup(args[1]);
+ curpeers->state = PR_STNEW;
}
else if (strcmp(args[0], "peer") == 0) { /* peer definition */
struct sockaddr_storage *sk;
@@ -1834,7 +1836,7 @@
curpeers->peers_fe->cap = PR_CAP_FE;
curpeers->peers_fe->maxconn = 0;
curpeers->peers_fe->conn_retries = CONN_RETRIES;
- curpeers->peers_fe->timeout.connect = 5000;
+ curpeers->peers_fe->timeout.client = MS_TO_TICKS(5000);
curpeers->peers_fe->accept = peer_accept;
curpeers->peers_fe->options2 |= PR_O2_INDEPSTR | PR_O2_SMARTCON | PR_O2_SMARTACC;
curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
@@ -1875,6 +1877,12 @@
}
}
} /* neither "peer" nor "peers" */
+ else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
+ curpeers->state = PR_STSTOPPED;
+ }
+ else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
+ curpeers->state = PR_STNEW;
+ }
else if (*args[0] != 0) {
Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
err_code |= ERR_ALERT | ERR_FATAL;
@@ -6107,6 +6115,8 @@
if (curproxy->state == PR_STSTOPPED) {
/* ensure we don't keep listeners uselessly bound */
stop_proxy(curproxy);
+ free((void *)curproxy->table.peers.name);
+ curproxy->table.peers.p = NULL;
continue;
}
@@ -6524,6 +6534,10 @@
curproxy->table.peers.p = NULL;
cfgerr++;
}
+ else if (curpeers->state == PR_STSTOPPED) {
+ /* silently disable this peers section */
+ curproxy->table.peers.p = NULL;
+ }
else if (!curpeers->peers_fe) {
Alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
curproxy->id, localpeer, curpeers->id);
@@ -7366,20 +7380,6 @@
}
}
- /* initialize stick-tables on backend capable proxies. This must not
- * be done earlier because the data size may be discovered while parsing
- * other proxies.
- */
- for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
- if (curproxy->state == PR_STSTOPPED)
- continue;
-
- if (!stktable_init(&curproxy->table)) {
- Alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
- cfgerr++;
- }
- }
-
/*
* Recount currently required checks.
*/
@@ -7407,14 +7407,23 @@
last = &peers;
while (*last) {
curpeers = *last;
- if (curpeers->peers_fe) {
+
+ if (curpeers->state == PR_STSTOPPED) {
+ /* the "disabled" keyword was present */
+ if (curpeers->peers_fe)
+ stop_proxy(curpeers->peers_fe);
+ curpeers->peers_fe = NULL;
+ }
+ else if (!curpeers->peers_fe) {
+ Warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
+ curpeers->id, localpeer);
+ }
+ else {
last = &curpeers->next;
continue;
}
- Warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
- curpeers->id, localpeer);
-
+ /* clean what has been detected above */
p = curpeers->remote;
while (p) {
pb = p->next;
@@ -7433,6 +7442,20 @@
}
}
+ /* initialize stick-tables on backend capable proxies. This must not
+ * be done earlier because the data size may be discovered while parsing
+ * other proxies.
+ */
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
+ if (curproxy->state == PR_STSTOPPED)
+ continue;
+
+ if (!stktable_init(&curproxy->table)) {
+ Alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
+ cfgerr++;
+ }
+ }
+
pool2_hdr_idx = create_pool("hdr_idx",
global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
MEM_F_SHARED);
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/checks.c
^
|
@@ -246,7 +246,7 @@
* cause the server to be marked down.
*/
if ((!(check->state & CHK_ST_AGENT) ||
- (check->status >= HCHK_STATUS_L7TOUT)) &&
+ (check->status >= HCHK_STATUS_L57DATA)) &&
(check->health >= check->rise)) {
s->counters.failed_checks++;
report = 1;
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/compression.c
^
|
@@ -130,9 +130,12 @@
{
int left;
- /* not enough space */
- if (in->size - buffer_len(in) < 40)
- return -1;
+ /* output stream requires at least 10 bytes for the gzip header, plus
+ * at least 8 bytes for the gzip trailer (crc+len), plus a possible
+ * plus at most 5 bytes per 32kB block and 2 bytes to close the stream.
+ */
+ if (in->size - buffer_len(in) < 20 + 5 * ((in->i + 32767) >> 15))
+ return -1;
/* We start by copying the current buffer's pending outgoing data into
* a new temporary buffer that we initialize with a new empty chunk.
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/haproxy.c
^
|
@@ -1579,7 +1579,7 @@
#ifdef USE_CPU_AFFINITY
if (proc < global.nbproc && /* child */
- proc < 32 && /* only the first 32 processes may be pinned */
+ proc < LONGBITS && /* only the first 32/64 processes may be pinned */
global.cpu_map[proc]) /* only do this if the process has a CPU map */
sched_setaffinity(0, sizeof(unsigned long), (void *)&global.cpu_map[proc]);
#endif
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/listener.c
^
|
@@ -120,9 +120,10 @@
* may replace enable_listener(). The resulting state will either be LI_READY
* or LI_FULL. 0 is returned in case of failure to resume (eg: dead socket).
* Listeners bound to a different process are not woken up unless we're in
- * foreground mode. If the listener was only in the assigned state, it's totally
- * rebound. This can happen if a pause() has completely stopped it. If the
- * resume fails, 0 is returned and an error might be displayed.
+ * foreground mode, and are ignored. If the listener was only in the assigned
+ * state, it's totally rebound. This can happen if a pause() has completely
+ * stopped it. If the resume fails, 0 is returned and an error might be
+ * displayed.
*/
int resume_listener(struct listener *l)
{
@@ -146,7 +147,7 @@
if ((global.mode & (MODE_DAEMON | MODE_SYSTEMD)) &&
l->bind_conf->bind_proc &&
!(l->bind_conf->bind_proc & (1UL << (relative_pid - 1))))
- return 0;
+ return 1;
if (l->proto->sock_prot == IPPROTO_TCP &&
l->state == LI_PAUSED &&
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/pattern.c
^
|
@@ -989,8 +989,10 @@
/* allocate pattern */
patl = calloc(1, sizeof(*patl));
- if (!patl)
+ if (!patl) {
+ memprintf(err, "out of memory while indexing pattern");
return 0;
+ }
/* duplicate pattern */
memcpy(&patl->pat, pat, sizeof(*pat));
@@ -1306,6 +1308,10 @@
struct ebmb_node *node, *next_node;
struct pattern_tree *elt;
+ /* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
+ if (expr->mflags & PAT_MF_IGNORE_CASE)
+ return pat_del_list_ptr(expr, ref);
+
/* browse each node of the tree. */
for (node = ebmb_first(&expr->pattern_tree), next_node = node ? ebmb_next(node) : NULL;
node;
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/proto_http.c
^
|
@@ -2478,7 +2478,6 @@
*/
int cur_idx;
- int use_close_only;
struct http_txn *txn = &s->txn;
struct http_msg *msg = &txn->req;
struct hdr_ctx ctx;
@@ -2621,6 +2620,9 @@
if (txn->flags & TX_WAIT_NEXT_RQ)
goto failed_keep_alive;
+ if (s->fe->options & PR_O_IGNORE_PRB)
+ goto failed_keep_alive;
+
/* we cannot return any message on error */
if (msg->err_pos >= 0) {
http_capture_bad_message(&s->fe->invalid_req, s, msg, msg->msg_state, s->fe);
@@ -2651,6 +2653,9 @@
if (txn->flags & TX_WAIT_NEXT_RQ)
goto failed_keep_alive;
+ if (s->fe->options & PR_O_IGNORE_PRB)
+ goto failed_keep_alive;
+
/* read timeout : give up with an error message. */
if (msg->err_pos >= 0) {
http_capture_bad_message(&s->fe->invalid_req, s, msg, msg->msg_state, s->fe);
@@ -2680,6 +2685,9 @@
if (txn->flags & TX_WAIT_NEXT_RQ)
goto failed_keep_alive;
+ if (s->fe->options & PR_O_IGNORE_PRB)
+ goto failed_keep_alive;
+
if (msg->err_pos >= 0)
http_capture_bad_message(&s->fe->invalid_req, s, msg, msg->msg_state, s->fe);
txn->status = 400;
@@ -2854,6 +2862,25 @@
if (unlikely(msg->sl.rq.v_l == 0) && !http_upgrade_v09_to_v10(txn))
goto return_bad_req;
+ /* RFC7230#2.6 has enforced the format of the HTTP version string to be
+ * exactly one digit "." one digit. This check may be disabled using
+ * option accept-invalid-http-request.
+ */
+ if (!(s->fe->options2 & PR_O2_REQBUG_OK)) {
+ if (msg->sl.rq.v_l != 8) {
+ msg->err_pos = msg->sl.rq.v;
+ goto return_bad_req;
+ }
+
+ if (req->buf->p[msg->sl.rq.v + 4] != '/' ||
+ !isdigit((unsigned char)req->buf->p[msg->sl.rq.v + 5]) ||
+ req->buf->p[msg->sl.rq.v + 6] != '.' ||
+ !isdigit((unsigned char)req->buf->p[msg->sl.rq.v + 7])) {
+ msg->err_pos = msg->sl.rq.v + 4;
+ goto return_bad_req;
+ }
+ }
+
/* ... and check if the request is HTTP/1.1 or above */
if ((msg->sl.rq.v_l == 8) &&
((req->buf->p[msg->sl.rq.v + 5] > '1') ||
@@ -2885,62 +2912,93 @@
capture_headers(req->buf->p, &txn->hdr_idx,
txn->req.cap, s->fe->req_cap);
- /* 6: determine the transfer-length.
- * According to RFC2616 #4.4, amended by the HTTPbis working group,
- * the presence of a message-body in a REQUEST and its transfer length
- * must be determined that way (in order of precedence) :
- * 1. The presence of a message-body in a request is signaled by the
- * inclusion of a Content-Length or Transfer-Encoding header field
- * in the request's header fields. When a request message contains
- * both a message-body of non-zero length and a method that does
- * not define any semantics for that request message-body, then an
- * origin server SHOULD either ignore the message-body or respond
- * with an appropriate error message (e.g., 413). A proxy or
- * gateway, when presented the same request, SHOULD either forward
- * the request inbound with the message- body or ignore the
- * message-body when determining a response.
+ /* 6: determine the transfer-length according to RFC2616 #4.4, updated
+ * by RFC7230#3.3.3 :
+ *
+ * The length of a message body is determined by one of the following
+ * (in order of precedence):
+ *
+ * 1. Any response to a HEAD request and any response with a 1xx
+ * (Informational), 204 (No Content), or 304 (Not Modified) status
+ * code is always terminated by the first empty line after the
+ * header fields, regardless of the header fields present in the
+ * message, and thus cannot contain a message body.
+ *
+ * 2. Any 2xx (Successful) response to a CONNECT request implies that
+ * the connection will become a tunnel immediately after the empty
+ * line that concludes the header fields. A client MUST ignore any
+ * Content-Length or Transfer-Encoding header fields received in
+ * such a message.
+ *
+ * 3. If a Transfer-Encoding header field is present and the chunked
+ * transfer coding (Section 4.1) is the final encoding, the message
+ * body length is determined by reading and decoding the chunked
+ * data until the transfer coding indicates the data is complete.
*
- * 2. If a Transfer-Encoding header field (Section 9.7) is present
- * and the "chunked" transfer-coding (Section 6.2) is used, the
- * transfer-length is defined by the use of this transfer-coding.
- * If a Transfer-Encoding header field is present and the "chunked"
- * transfer-coding is not present, the transfer-length is defined
- * by the sender closing the connection.
+ * If a Transfer-Encoding header field is present in a response and
+ * the chunked transfer coding is not the final encoding, the
+ * message body length is determined by reading the connection until
+ * it is closed by the server. If a Transfer-Encoding header field
+ * is present in a request and the chunked transfer coding is not
+ * the final encoding, the message body length cannot be determined
+ * reliably; the server MUST respond with the 400 (Bad Request)
+ * status code and then close the connection.
*
- * 3. If a Content-Length header field is present, its decimal value in
- * OCTETs represents both the entity-length and the transfer-length.
- * If a message is received with both a Transfer-Encoding header
- * field and a Content-Length header field, the latter MUST be ignored.
+ * If a message is received with both a Transfer-Encoding and a
+ * Content-Length header field, the Transfer-Encoding overrides the
+ * Content-Length. Such a message might indicate an attempt to
+ * perform request smuggling (Section 9.5) or response splitting
+ * (Section 9.4) and ought to be handled as an error. A sender MUST
+ * remove the received Content-Length field prior to forwarding such
+ * a message downstream.
*
- * 4. By the server closing the connection. (Closing the connection
- * cannot be used to indicate the end of a request body, since that
- * would leave no possibility for the server to send back a response.)
+ * 4. If a message is received without Transfer-Encoding and with
+ * either multiple Content-Length header fields having differing
+ * field-values or a single Content-Length header field having an
+ * invalid value, then the message framing is invalid and the
+ * recipient MUST treat it as an unrecoverable error. If this is a
+ * request message, the server MUST respond with a 400 (Bad Request)
+ * status code and then close the connection. If this is a response
+ * message received by a proxy, the proxy MUST close the connection
+ * to the server, discard the received response, and send a 502 (Bad
+ * Gateway) response to the client. If this is a response message
+ * received by a user agent, the user agent MUST close the
+ * connection to the server and discard the received response.
*
- * Whenever a transfer-coding is applied to a message-body, the set of
- * transfer-codings MUST include "chunked", unless the message indicates
- * it is terminated by closing the connection. When the "chunked"
- * transfer-coding is used, it MUST be the last transfer-coding applied
- * to the message-body.
+ * 5. If a valid Content-Length header field is present without
+ * Transfer-Encoding, its decimal value defines the expected message
+ * body length in octets. If the sender closes the connection or
+ * the recipient times out before the indicated number of octets are
+ * received, the recipient MUST consider the message to be
+ * incomplete and close the connection.
+ *
+ * 6. If this is a request message and none of the above are true, then
+ * the message body length is zero (no message body is present).
+ *
+ * 7. Otherwise, this is a response message without a declared message
+ * body length, so the message body length is determined by the
+ * number of octets received prior to the server closing the
+ * connection.
*/
- use_close_only = 0;
ctx.idx = 0;
/* set TE_CHNK and XFER_LEN only if "chunked" is seen last */
- while ((msg->flags & HTTP_MSGF_VER_11) &&
- http_find_header2("Transfer-Encoding", 17, req->buf->p, &txn->hdr_idx, &ctx)) {
+ while (http_find_header2("Transfer-Encoding", 17, req->buf->p, &txn->hdr_idx, &ctx)) {
if (ctx.vlen == 7 && strncasecmp(ctx.line + ctx.val, "chunked", 7) == 0)
msg->flags |= (HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
else if (msg->flags & HTTP_MSGF_TE_CHNK) {
- /* bad transfer-encoding (chunked followed by something else) */
- use_close_only = 1;
- msg->flags &= ~(HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
- break;
+ /* chunked not last, return badreq */
+ goto return_bad_req;
}
}
+ /* Chunked requests must have their content-length removed */
ctx.idx = 0;
- while (!(msg->flags & HTTP_MSGF_TE_CHNK) && !use_close_only &&
- http_find_header2("Content-Length", 14, req->buf->p, &txn->hdr_idx, &ctx)) {
+ if (msg->flags & HTTP_MSGF_TE_CHNK) {
+ while (http_find_header2("Content-Length", 14, req->buf->p, &txn->hdr_idx, &ctx))
+ http_remove_header2(msg, &txn->hdr_idx, &ctx);
+ }
+ else while (http_find_header2("Content-Length", 14, req->buf->p, &txn->hdr_idx, &ctx)) {
signed long long cl;
if (!ctx.vlen) {
@@ -2967,9 +3025,8 @@
msg->body_len = msg->chunk_len = cl;
}
- /* bodyless requests have a known length */
- if (!use_close_only)
- msg->flags |= HTTP_MSGF_XFER_LEN;
+ /* even bodyless requests have a known length */
+ msg->flags |= HTTP_MSGF_XFER_LEN;
/* Until set to anything else, the connection mode is set as Keep-Alive. It will
* only change if both the request and the config reference something else.
@@ -3179,113 +3236,55 @@
#endif
}
-/* Returns the number of characters written to destination,
- * -1 on internal error and -2 if no replacement took place.
- */
-static int http_replace_header(struct my_regex *re, char *dst, uint dst_size, char *val, int len,
- const char *rep_str)
-{
- if (!regex_exec_match2(re, val, len, MAX_MATCH, pmatch))
- return -2;
-
- return exp_replace(dst, dst_size, val, rep_str, pmatch);
-}
-
-/* Returns the number of characters written to destination,
- * -1 on internal error and -2 if no replacement took place.
- */
-static int http_replace_value(struct my_regex *re, char *dst, uint dst_size, char *val, int len, char delim,
- const char *rep_str)
-{
- char* p = val;
- char* dst_end = dst + dst_size;
- char* dst_p = dst;
-
- for (;;) {
- char *p_delim;
-
- /* look for delim. */
- p_delim = p;
- while (p_delim < p + len && *p_delim != delim)
- p_delim++;
-
- if (regex_exec_match2(re, p, p_delim-p, MAX_MATCH, pmatch)) {
- int replace_n = exp_replace(dst_p, dst_end - dst_p, p, rep_str, pmatch);
-
- if (replace_n < 0)
- return -1;
-
- dst_p += replace_n;
- } else {
- uint len = p_delim - p;
-
- if (dst_p + len >= dst_end)
- return -1;
-
- memcpy(dst_p, p, len);
- dst_p += len;
- }
-
- if (dst_p >= dst_end)
- return -1;
-
- /* end of the replacements. */
- if (p_delim >= p + len)
- break;
-
- /* Next part. */
- *dst_p++ = delim;
- p = p_delim + 1;
- }
-
- return dst_p - dst;
-}
-
static int http_transform_header(struct session* s, struct http_msg *msg, const char* name, uint name_len,
char* buf, struct hdr_idx* idx, struct list *fmt, struct my_regex *re,
struct hdr_ctx* ctx, int action)
{
+ int (*http_find_hdr_func)(const char *name, int len, char *sol,
+ struct hdr_idx *idx, struct hdr_ctx *ctx);
+ struct chunk *replace = get_trash_chunk();
+ struct chunk *output = get_trash_chunk();
+
+ replace->len = build_logline(s, replace->str, replace->size, fmt);
+ if (replace->len >= replace->size - 1)
+ return -1;
+
ctx->idx = 0;
- while (http_find_full_header2(name, name_len, buf, idx, ctx)) {
+ /* Choose the header browsing function. */
+ switch (action) {
+ case HTTP_REQ_ACT_REPLACE_VAL:
+ case HTTP_RES_ACT_REPLACE_VAL:
+ http_find_hdr_func = http_find_header2;
+ break;
+ case HTTP_REQ_ACT_REPLACE_HDR:
+ case HTTP_RES_ACT_REPLACE_HDR:
+ http_find_hdr_func = http_find_full_header2;
+ break;
+ default: /* impossible */
+ return -1;
+ }
+
+ while (http_find_hdr_func(name, name_len, buf, idx, ctx)) {
struct hdr_idx_elem *hdr = idx->v + ctx->idx;
int delta;
- char* val = (char*)ctx->line + ctx->val;
- char* val_end = (char*)ctx->line + hdr->len;
- char* reg_dst_buf;
- uint reg_dst_buf_size;
- int n_replaced;
+ char *val = ctx->line + ctx->val;
+ char* val_end = val + ctx->vlen;
- trash.len = build_logline(s, trash.str, trash.size, fmt);
+ if (!regex_exec_match2(re, val, val_end-val, MAX_MATCH, pmatch))
+ continue;
- if (trash.len >= trash.size - 1)
+ output->len = exp_replace(output->str, output->size, val, replace->str, pmatch);
+ if (output->len == -1)
return -1;
- reg_dst_buf = trash.str + trash.len + 1;
- reg_dst_buf_size = trash.size - trash.len - 1;
-
- switch (action) {
- case HTTP_REQ_ACT_REPLACE_VAL:
- case HTTP_RES_ACT_REPLACE_VAL:
- n_replaced = http_replace_value(re, reg_dst_buf, reg_dst_buf_size, val, val_end-val, ',', trash.str);
- break;
- case HTTP_REQ_ACT_REPLACE_HDR:
- case HTTP_RES_ACT_REPLACE_HDR:
- n_replaced = http_replace_header(re, reg_dst_buf, reg_dst_buf_size, val, val_end-val, trash.str);
- break;
- default: /* impossible */
- return -1;
- }
-
- switch (n_replaced) {
- case -1: return -1;
- case -2: continue;
- }
-
- delta = buffer_replace2(msg->chn->buf, val, val_end, reg_dst_buf, n_replaced);
+ delta = buffer_replace2(msg->chn->buf, val, val_end, output->str, output->len);
hdr->len += delta;
http_msg_move_end(msg, delta);
+
+ /* Adjust the length of the current value of the index. */
+ ctx->vlen += delta;
}
return 0;
@@ -4649,7 +4648,7 @@
if (!(msg->flags & HTTP_MSGF_TE_CHNK)) {
/* We're in content-length mode, we just have to wait for enough data. */
- if (req->buf->i - msg->sov < msg->body_len)
+ if (http_body_bytes(msg) < msg->body_len)
goto missing_data;
/* OK we have everything we need now */
@@ -4674,13 +4673,14 @@
}
/* Now we're in HTTP_MSG_DATA or HTTP_MSG_TRAILERS state.
- * We have the first data byte is in msg->sov. We're waiting for at
- * least a whole chunk or the whole content length bytes after msg->sov.
+ * We have the first data byte is in msg->sov + msg->sol. We're waiting
+ * for at least a whole chunk or the whole content length bytes after
+ * msg->sov + msg->sol.
*/
if (msg->msg_state == HTTP_MSG_TRAILERS)
goto http_end;
- if (req->buf->i - msg->sov >= msg->body_len) /* we have enough bytes now */
+ if (http_body_bytes(msg) >= msg->body_len) /* we have enough bytes now */
goto http_end;
missing_data:
@@ -5899,6 +5899,25 @@
if (objt_server(s->target))
objt_server(s->target)->counters.p.http.rsp[n]++;
+ /* RFC7230#2.6 has enforced the format of the HTTP version string to be
+ * exactly one digit "." one digit. This check may be disabled using
+ * option accept-invalid-http-response.
+ */
+ if (!(s->be->options2 & PR_O2_RSPBUG_OK)) {
+ if (msg->sl.st.v_l != 8) {
+ msg->err_pos = 0;
+ goto hdr_response_bad;
+ }
+
+ if (rep->buf->p[4] != '/' ||
+ !isdigit((unsigned char)rep->buf->p[5]) ||
+ rep->buf->p[6] != '.' ||
+ !isdigit((unsigned char)rep->buf->p[7])) {
+ msg->err_pos = 4;
+ goto hdr_response_bad;
+ }
+ }
+
/* check if the response is HTTP/1.1 or above */
if ((msg->sl.st.v_l == 8) &&
((rep->buf->p[5] > '1') ||
@@ -5976,44 +5995,73 @@
capture_headers(rep->buf->p, &txn->hdr_idx,
txn->rsp.cap, s->fe->rsp_cap);
- /* 4: determine the transfer-length.
- * According to RFC2616 #4.4, amended by the HTTPbis working group,
- * the presence of a message-body in a RESPONSE and its transfer length
- * must be determined that way :
+ /* 4: determine the transfer-length according to RFC2616 #4.4, updated
+ * by RFC7230#3.3.3 :
+ *
+ * The length of a message body is determined by one of the following
+ * (in order of precedence):
+ *
+ * 1. Any response to a HEAD request and any response with a 1xx
+ * (Informational), 204 (No Content), or 304 (Not Modified) status
+ * code is always terminated by the first empty line after the
+ * header fields, regardless of the header fields present in the
+ * message, and thus cannot contain a message body.
+ *
+ * 2. Any 2xx (Successful) response to a CONNECT request implies that
+ * the connection will become a tunnel immediately after the empty
+ * line that concludes the header fields. A client MUST ignore any
+ * Content-Length or Transfer-Encoding header fields received in
+ * such a message.
+ *
+ * 3. If a Transfer-Encoding header field is present and the chunked
+ * transfer coding (Section 4.1) is the final encoding, the message
+ * body length is determined by reading and decoding the chunked
+ * data until the transfer coding indicates the data is complete.
*
- * All responses to the HEAD request method MUST NOT include a
- * message-body, even though the presence of entity-header fields
- * might lead one to believe they do. All 1xx (informational), 204
- * (No Content), and 304 (Not Modified) responses MUST NOT include a
- * message-body. All other responses do include a message-body,
- * although it MAY be of zero length.
+ * If a Transfer-Encoding header field is present in a response and
+ * the chunked transfer coding is not the final encoding, the
+ * message body length is determined by reading the connection until
+ * it is closed by the server. If a Transfer-Encoding header field
+ * is present in a request and the chunked transfer coding is not
+ * the final encoding, the message body length cannot be determined
+ * reliably; the server MUST respond with the 400 (Bad Request)
+ * status code and then close the connection.
*
- * 1. Any response which "MUST NOT" include a message-body (such as the
- * 1xx, 204 and 304 responses and any response to a HEAD request) is
- * always terminated by the first empty line after the header fields,
- * regardless of the entity-header fields present in the message.
+ * If a message is received with both a Transfer-Encoding and a
+ * Content-Length header field, the Transfer-Encoding overrides the
+ * Content-Length. Such a message might indicate an attempt to
+ * perform request smuggling (Section 9.5) or response splitting
+ * (Section 9.4) and ought to be handled as an error. A sender MUST
+ * remove the received Content-Length field prior to forwarding such
+ * a message downstream.
*
- * 2. If a Transfer-Encoding header field (Section 9.7) is present and
- * the "chunked" transfer-coding (Section 6.2) is used, the
- * transfer-length is defined by the use of this transfer-coding.
- * If a Transfer-Encoding header field is present and the "chunked"
- * transfer-coding is not present, the transfer-length is defined by
- * the sender closing the connection.
+ * 4. If a message is received without Transfer-Encoding and with
+ * either multiple Content-Length header fields having differing
+ * field-values or a single Content-Length header field having an
+ * invalid value, then the message framing is invalid and the
+ * recipient MUST treat it as an unrecoverable error. If this is a
+ * request message, the server MUST respond with a 400 (Bad Request)
+ * status code and then close the connection. If this is a response
+ * message received by a proxy, the proxy MUST close the connection
+ * to the server, discard the received response, and send a 502 (Bad
+ * Gateway) response to the client. If this is a response message
+ * received by a user agent, the user agent MUST close the
+ * connection to the server and discard the received response.
*
- * 3. If a Content-Length header field is present, its decimal value in
- * OCTETs represents both the entity-length and the transfer-length.
- * If a message is received with both a Transfer-Encoding header
- * field and a Content-Length header field, the latter MUST be ignored.
+ * 5. If a valid Content-Length header field is present without
+ * Transfer-Encoding, its decimal value defines the expected message
+ * body length in octets. If the sender closes the connection or
+ * the recipient times out before the indicated number of octets are
+ * received, the recipient MUST consider the message to be
+ * incomplete and close the connection.
*
- * 4. If the message uses the media type "multipart/byteranges", and
- * the transfer-length is not otherwise specified, then this self-
- * delimiting media type defines the transfer-length. This media
- * type MUST NOT be used unless the sender knows that the recipient
- * can parse it; the presence in a request of a Range header with
- * multiple byte-range specifiers from a 1.1 client implies that the
- * client can parse multipart/byteranges responses.
+ * 6. If this is a request message and none of the above are true, then
+ * the message body length is zero (no message body is present).
*
- * 5. By the server closing the connection.
+ * 7. Otherwise, this is a response message without a declared message
+ * body length, so the message body length is determined by the
+ * number of octets received prior to the server closing the
+ * connection.
*/
/* Skip parsing if no content length is possible. The response flags
@@ -6031,8 +6079,7 @@
use_close_only = 0;
ctx.idx = 0;
- while ((msg->flags & HTTP_MSGF_VER_11) &&
- http_find_header2("Transfer-Encoding", 17, rep->buf->p, &txn->hdr_idx, &ctx)) {
+ while (http_find_header2("Transfer-Encoding", 17, rep->buf->p, &txn->hdr_idx, &ctx)) {
if (ctx.vlen == 7 && strncasecmp(ctx.line + ctx.val, "chunked", 7) == 0)
msg->flags |= (HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
else if (msg->flags & HTTP_MSGF_TE_CHNK) {
@@ -6043,10 +6090,13 @@
}
}
- /* FIXME: below we should remove the content-length header(s) in case of chunked encoding */
+ /* Chunked responses must have their content-length removed */
ctx.idx = 0;
- while (!(msg->flags & HTTP_MSGF_TE_CHNK) && !use_close_only &&
- http_find_header2("Content-Length", 14, rep->buf->p, &txn->hdr_idx, &ctx)) {
+ if (use_close_only || (msg->flags & HTTP_MSGF_TE_CHNK)) {
+ while (http_find_header2("Content-Length", 14, rep->buf->p, &txn->hdr_idx, &ctx))
+ http_remove_header2(msg, &txn->hdr_idx, &ctx);
+ }
+ else while (http_find_header2("Content-Length", 14, rep->buf->p, &txn->hdr_idx, &ctx)) {
signed long long cl;
if (!ctx.vlen) {
@@ -10072,15 +10122,19 @@
struct hdr_ctx ctx;
const struct http_msg *msg = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) ? &txn->req : &txn->rsp;
int cnt;
+ const char *name = NULL;
+ int len = 0;
- if (!args || args->type != ARGT_STR)
- return 0;
+ if (args && args->type == ARGT_STR) {
+ name = args->data.str.str;
+ len = args->data.str.len;
+ }
CHECK_HTTP_MESSAGE_FIRST();
ctx.idx = 0;
cnt = 0;
- while (http_find_full_header2(args->data.str.str, args->data.str.len, msg->chn->buf->p, idx, &ctx))
+ while (http_find_full_header2(name, len, msg->chn->buf->p, idx, &ctx))
cnt++;
smp->type = SMP_T_UINT;
@@ -10159,15 +10213,19 @@
struct hdr_ctx ctx;
const struct http_msg *msg = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) ? &txn->req : &txn->rsp;
int cnt;
+ const char *name = NULL;
+ int len = 0;
- if (!args || args->type != ARGT_STR)
- return 0;
+ if (args && args->type == ARGT_STR) {
+ name = args->data.str.str;
+ len = args->data.str.len;
+ }
CHECK_HTTP_MESSAGE_FIRST();
ctx.idx = 0;
cnt = 0;
- while (http_find_header2(args->data.str.str, args->data.str.len, msg->chn->buf->p, idx, &ctx))
+ while (http_find_header2(name, len, msg->chn->buf->p, idx, &ctx))
cnt++;
smp->type = SMP_T_UINT;
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/ssl_sock.c
^
|
@@ -1569,7 +1569,7 @@
if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
- curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
+ curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
cfgerr++;
}
else {
|
[-]
[+]
|
Changed |
_service:download_url:haproxy-1.5.12.tar.gz/src/stick_table.c
^
|
@@ -395,7 +395,7 @@
t->exp_task->expire = TICK_ETERNITY;
t->exp_task->context = (void *)t;
}
- if (t->peers.p && t->peers.p->peers_fe) {
+ if (t->peers.p && t->peers.p->peers_fe && t->peers.p->peers_fe->state != PR_STSTOPPED) {
peers_register_table(t->peers.p, t);
}
|