blob: 19ab0a3709b8d0054ce5975a8e4d23610eed6e35 [file] [log] [blame]
Christopher Fauletf4eb75d2018-10-11 15:55:07 +02001/*
2 * HTTP protocol analyzer
3 *
4 * Copyright (C) 2018 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
Christopher Faulete0768eb2018-10-03 16:38:02 +020013#include <common/base64.h>
14#include <common/config.h>
15#include <common/debug.h>
16#include <common/uri_auth.h>
17
18#include <types/cache.h>
Christopher Faulet0f226952018-10-22 09:29:56 +020019#include <types/capture.h>
Christopher Faulete0768eb2018-10-03 16:38:02 +020020
21#include <proto/acl.h>
22#include <proto/channel.h>
23#include <proto/checks.h>
24#include <proto/connection.h>
25#include <proto/filters.h>
26#include <proto/hdr_idx.h>
Christopher Faulet0f226952018-10-22 09:29:56 +020027#include <proto/http_htx.h>
28#include <proto/htx.h>
Christopher Faulete0768eb2018-10-03 16:38:02 +020029#include <proto/log.h>
30#include <proto/proto_http.h>
31#include <proto/proxy.h>
32#include <proto/stream.h>
33#include <proto/stream_interface.h>
34#include <proto/stats.h>
35
Christopher Fauletf2824e62018-10-01 12:12:37 +020036
37static void htx_end_request(struct stream *s);
38static void htx_end_response(struct stream *s);
39
Christopher Faulet0f226952018-10-22 09:29:56 +020040static void htx_capture_headers(struct htx *htx, char **cap, struct cap_hdr *cap_hdr);
Christopher Faulet0b6bdc52018-10-24 11:05:36 +020041static int htx_del_hdr_value(char *start, char *end, char **from, char *next);
Christopher Faulet0f226952018-10-22 09:29:56 +020042static size_t htx_fmt_req_line(const union h1_sl sl, char *str, size_t len);
43static void htx_debug_stline(const char *dir, struct stream *s, const union h1_sl sl);
44static void htx_debug_hdr(const char *dir, struct stream *s, const struct ist n, const struct ist v);
45
Christopher Faulete0768eb2018-10-03 16:38:02 +020046/* This stream analyser waits for a complete HTTP request. It returns 1 if the
47 * processing can continue on next analysers, or zero if it either needs more
48 * data or wants to immediately abort the request (eg: timeout, error, ...). It
49 * is tied to AN_REQ_WAIT_HTTP and may may remove itself from s->req.analysers
50 * when it has nothing left to do, and may remove any analyser when it wants to
51 * abort.
52 */
53int htx_wait_for_request(struct stream *s, struct channel *req, int an_bit)
54{
Christopher Faulet9768c262018-10-22 09:34:31 +020055
Christopher Faulete0768eb2018-10-03 16:38:02 +020056 /*
Christopher Faulet9768c262018-10-22 09:34:31 +020057 * We will analyze a complete HTTP request to check the its syntax.
Christopher Faulete0768eb2018-10-03 16:38:02 +020058 *
Christopher Faulet9768c262018-10-22 09:34:31 +020059 * Once the start line and all headers are received, we may perform a
60 * capture of the error (if any), and we will set a few fields. We also
61 * check for monitor-uri, logging and finally headers capture.
Christopher Faulete0768eb2018-10-03 16:38:02 +020062 */
Christopher Faulete0768eb2018-10-03 16:38:02 +020063 struct session *sess = s->sess;
64 struct http_txn *txn = s->txn;
65 struct http_msg *msg = &txn->req;
Christopher Faulet9768c262018-10-22 09:34:31 +020066 struct htx *htx;
67 union h1_sl sl;
Christopher Faulete0768eb2018-10-03 16:38:02 +020068
69 DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
70 now_ms, __FUNCTION__,
71 s,
72 req,
73 req->rex, req->wex,
74 req->flags,
75 ci_data(req),
76 req->analysers);
77
Christopher Faulet9768c262018-10-22 09:34:31 +020078 htx = htx_from_buf(&req->buf);
79
Christopher Faulete0768eb2018-10-03 16:38:02 +020080 /* we're speaking HTTP here, so let's speak HTTP to the client */
81 s->srv_error = http_return_srv_error;
82
83 /* If there is data available for analysis, log the end of the idle time. */
84 if (c_data(req) && s->logs.t_idle == -1)
85 s->logs.t_idle = tv_ms_elapsed(&s->logs.tv_accept, &now) - s->logs.t_handshake;
86
Christopher Faulete0768eb2018-10-03 16:38:02 +020087 /*
88 * Now we quickly check if we have found a full valid request.
89 * If not so, we check the FD and buffer states before leaving.
90 * A full request is indicated by the fact that we have seen
91 * the double LF/CRLF, so the state is >= HTTP_MSG_BODY. Invalid
92 * requests are checked first. When waiting for a second request
93 * on a keep-alive stream, if we encounter and error, close, t/o,
94 * we note the error in the stream flags but don't set any state.
95 * Since the error will be noted there, it will not be counted by
96 * process_stream() as a frontend error.
97 * Last, we may increase some tracked counters' http request errors on
98 * the cases that are deliberately the client's fault. For instance,
99 * a timeout or connection reset is not counted as an error. However
100 * a bad request is.
101 */
Christopher Faulet9768c262018-10-22 09:34:31 +0200102 if (unlikely(htx_is_empty(htx) || htx_get_tail_type(htx) < HTX_BLK_EOH)) {
103 /* 1: have we encountered a read error ? */
104 if (req->flags & CF_READ_ERROR) {
Christopher Faulete0768eb2018-10-03 16:38:02 +0200105 if (!(s->flags & SF_ERR_MASK))
106 s->flags |= SF_ERR_CLICL;
107
108 if (txn->flags & TX_WAIT_NEXT_RQ)
109 goto failed_keep_alive;
110
111 if (sess->fe->options & PR_O_IGNORE_PRB)
112 goto failed_keep_alive;
113
Christopher Faulet9768c262018-10-22 09:34:31 +0200114 stream_inc_http_err_ctr(s);
Christopher Faulete0768eb2018-10-03 16:38:02 +0200115 stream_inc_http_req_ctr(s);
116 proxy_inc_fe_req_ctr(sess->fe);
117 HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_req, 1);
118 if (sess->listener->counters)
119 HA_ATOMIC_ADD(&sess->listener->counters->failed_req, 1);
120
Christopher Faulet9768c262018-10-22 09:34:31 +0200121 txn->status = 400;
122 msg->err_state = msg->msg_state;
123 msg->msg_state = HTTP_MSG_ERROR;
124 htx_reply_and_close(s, txn->status, NULL);
125 req->analysers &= AN_REQ_FLT_END;
126
Christopher Faulete0768eb2018-10-03 16:38:02 +0200127 if (!(s->flags & SF_FINST_MASK))
128 s->flags |= SF_FINST_R;
129 return 0;
130 }
131
Christopher Faulet9768c262018-10-22 09:34:31 +0200132 /* 2: has the read timeout expired ? */
Christopher Faulete0768eb2018-10-03 16:38:02 +0200133 else if (req->flags & CF_READ_TIMEOUT || tick_is_expired(req->analyse_exp, now_ms)) {
134 if (!(s->flags & SF_ERR_MASK))
135 s->flags |= SF_ERR_CLITO;
136
137 if (txn->flags & TX_WAIT_NEXT_RQ)
138 goto failed_keep_alive;
139
140 if (sess->fe->options & PR_O_IGNORE_PRB)
141 goto failed_keep_alive;
142
Christopher Faulet9768c262018-10-22 09:34:31 +0200143 stream_inc_http_err_ctr(s);
Christopher Faulete0768eb2018-10-03 16:38:02 +0200144 stream_inc_http_req_ctr(s);
145 proxy_inc_fe_req_ctr(sess->fe);
146 HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_req, 1);
147 if (sess->listener->counters)
148 HA_ATOMIC_ADD(&sess->listener->counters->failed_req, 1);
149
Christopher Faulet9768c262018-10-22 09:34:31 +0200150 txn->status = 408;
151 msg->err_state = msg->msg_state;
152 msg->msg_state = HTTP_MSG_ERROR;
153 htx_reply_and_close(s, txn->status, http_error_message(s));
154 req->analysers &= AN_REQ_FLT_END;
155
Christopher Faulete0768eb2018-10-03 16:38:02 +0200156 if (!(s->flags & SF_FINST_MASK))
157 s->flags |= SF_FINST_R;
158 return 0;
159 }
160
Christopher Faulet9768c262018-10-22 09:34:31 +0200161 /* 3: have we encountered a close ? */
Christopher Faulete0768eb2018-10-03 16:38:02 +0200162 else if (req->flags & CF_SHUTR) {
163 if (!(s->flags & SF_ERR_MASK))
164 s->flags |= SF_ERR_CLICL;
165
166 if (txn->flags & TX_WAIT_NEXT_RQ)
167 goto failed_keep_alive;
168
169 if (sess->fe->options & PR_O_IGNORE_PRB)
170 goto failed_keep_alive;
171
Christopher Faulete0768eb2018-10-03 16:38:02 +0200172 stream_inc_http_err_ctr(s);
173 stream_inc_http_req_ctr(s);
174 proxy_inc_fe_req_ctr(sess->fe);
175 HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_req, 1);
176 if (sess->listener->counters)
177 HA_ATOMIC_ADD(&sess->listener->counters->failed_req, 1);
178
Christopher Faulet9768c262018-10-22 09:34:31 +0200179 txn->status = 400;
180 msg->err_state = msg->msg_state;
181 msg->msg_state = HTTP_MSG_ERROR;
182 htx_reply_and_close(s, txn->status, http_error_message(s));
183 req->analysers &= AN_REQ_FLT_END;
184
Christopher Faulete0768eb2018-10-03 16:38:02 +0200185 if (!(s->flags & SF_FINST_MASK))
186 s->flags |= SF_FINST_R;
187 return 0;
188 }
189
190 channel_dont_connect(req);
191 req->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */
192 s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
193#ifdef TCP_QUICKACK
Christopher Faulet9768c262018-10-22 09:34:31 +0200194 if (sess->listener->options & LI_O_NOQUICKACK && htx_is_not_empty(htx) &&
Christopher Faulete0768eb2018-10-03 16:38:02 +0200195 objt_conn(sess->origin) && conn_ctrl_ready(__objt_conn(sess->origin))) {
196 /* We need more data, we have to re-enable quick-ack in case we
197 * previously disabled it, otherwise we might cause the client
198 * to delay next data.
199 */
200 setsockopt(__objt_conn(sess->origin)->handle.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
201 }
202#endif
203
204 if ((msg->msg_state != HTTP_MSG_RQBEFORE) && (txn->flags & TX_WAIT_NEXT_RQ)) {
205 /* If the client starts to talk, let's fall back to
206 * request timeout processing.
207 */
208 txn->flags &= ~TX_WAIT_NEXT_RQ;
209 req->analyse_exp = TICK_ETERNITY;
210 }
211
212 /* just set the request timeout once at the beginning of the request */
213 if (!tick_isset(req->analyse_exp)) {
214 if ((msg->msg_state == HTTP_MSG_RQBEFORE) &&
215 (txn->flags & TX_WAIT_NEXT_RQ) &&
216 tick_isset(s->be->timeout.httpka))
217 req->analyse_exp = tick_add(now_ms, s->be->timeout.httpka);
218 else
219 req->analyse_exp = tick_add_ifset(now_ms, s->be->timeout.httpreq);
220 }
221
222 /* we're not ready yet */
223 return 0;
224
225 failed_keep_alive:
226 /* Here we process low-level errors for keep-alive requests. In
227 * short, if the request is not the first one and it experiences
228 * a timeout, read error or shutdown, we just silently close so
229 * that the client can try again.
230 */
231 txn->status = 0;
232 msg->msg_state = HTTP_MSG_RQBEFORE;
233 req->analysers &= AN_REQ_FLT_END;
234 s->logs.logwait = 0;
235 s->logs.level = 0;
236 s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
Christopher Faulet9768c262018-10-22 09:34:31 +0200237 htx_reply_and_close(s, txn->status, NULL);
Christopher Faulete0768eb2018-10-03 16:38:02 +0200238 return 0;
239 }
240
Christopher Faulet9768c262018-10-22 09:34:31 +0200241 msg->msg_state = HTTP_MSG_BODY;
Christopher Faulete0768eb2018-10-03 16:38:02 +0200242 stream_inc_http_req_ctr(s);
243 proxy_inc_fe_req_ctr(sess->fe); /* one more valid request for this FE */
244
Christopher Faulet9768c262018-10-22 09:34:31 +0200245 /* kill the pending keep-alive timeout */
246 txn->flags &= ~TX_WAIT_NEXT_RQ;
247 req->analyse_exp = TICK_ETERNITY;
Christopher Faulete0768eb2018-10-03 16:38:02 +0200248
Christopher Faulet9768c262018-10-22 09:34:31 +0200249 /* 0: we might have to print this header in debug mode */
250 if (unlikely((global.mode & MODE_DEBUG) &&
251 (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
252 int32_t pos;
Christopher Faulete0768eb2018-10-03 16:38:02 +0200253
Christopher Faulet9768c262018-10-22 09:34:31 +0200254 htx_debug_stline("clireq", s, http_find_stline(htx));
255
256 for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
257 struct htx_blk *blk = htx_get_blk(htx, pos);
258 enum htx_blk_type type = htx_get_blk_type(blk);
259
260 if (type == HTX_BLK_EOH)
261 break;
262 if (type != HTX_BLK_HDR)
263 continue;
264
265 htx_debug_hdr("clihdr", s,
266 htx_get_blk_name(htx, blk),
267 htx_get_blk_value(htx, blk));
268 }
269 }
Christopher Faulete0768eb2018-10-03 16:38:02 +0200270
271 /*
272 * 1: identify the method
273 */
Christopher Faulet9768c262018-10-22 09:34:31 +0200274 sl = http_find_stline(htx);
275 txn->meth = sl.rq.meth;
276 msg->flags |= HTTP_MSGF_XFER_LEN;
277
278 /* ... and check if the request is HTTP/1.1 or above */
279 if ((sl.rq.v.len == 8) &&
280 ((*(sl.rq.v.ptr + 5) > '1') ||
281 ((*(sl.rq.v.ptr + 5) == '1') && (*(sl.rq.v.ptr + 7) >= '1'))))
282 msg->flags |= HTTP_MSGF_VER_11;
Christopher Faulete0768eb2018-10-03 16:38:02 +0200283
284 /* we can make use of server redirect on GET and HEAD */
285 if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
286 s->flags |= SF_REDIRECTABLE;
Christopher Faulet9768c262018-10-22 09:34:31 +0200287 else if (txn->meth == HTTP_METH_OTHER && isteqi(sl.rq.m, ist("PRI"))) {
Christopher Faulete0768eb2018-10-03 16:38:02 +0200288 /* PRI is reserved for the HTTP/2 preface */
Christopher Faulete0768eb2018-10-03 16:38:02 +0200289 goto return_bad_req;
290 }
291
292 /*
293 * 2: check if the URI matches the monitor_uri.
294 * We have to do this for every request which gets in, because
295 * the monitor-uri is defined by the frontend.
296 */
297 if (unlikely((sess->fe->monitor_uri_len != 0) &&
Christopher Faulet9768c262018-10-22 09:34:31 +0200298 isteqi(sl.rq.u, ist2(sess->fe->monitor_uri, sess->fe->monitor_uri_len)))) {
Christopher Faulete0768eb2018-10-03 16:38:02 +0200299 /*
300 * We have found the monitor URI
301 */
302 struct acl_cond *cond;
303
304 s->flags |= SF_MONITOR;
305 HA_ATOMIC_ADD(&sess->fe->fe_counters.intercepted_req, 1);
306
307 /* Check if we want to fail this monitor request or not */
308 list_for_each_entry(cond, &sess->fe->mon_fail_cond, list) {
309 int ret = acl_exec_cond(cond, sess->fe, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
310
311 ret = acl_pass(ret);
312 if (cond->pol == ACL_COND_UNLESS)
313 ret = !ret;
314
315 if (ret) {
316 /* we fail this request, let's return 503 service unavail */
317 txn->status = 503;
Christopher Faulet9768c262018-10-22 09:34:31 +0200318 htx_reply_and_close(s, txn->status, http_error_message(s));
Christopher Faulete0768eb2018-10-03 16:38:02 +0200319 if (!(s->flags & SF_ERR_MASK))
320 s->flags |= SF_ERR_LOCAL; /* we don't want a real error here */
321 goto return_prx_cond;
322 }
323 }
324
325 /* nothing to fail, let's reply normaly */
326 txn->status = 200;
Christopher Faulet9768c262018-10-22 09:34:31 +0200327 htx_reply_and_close(s, txn->status, http_error_message(s));
Christopher Faulete0768eb2018-10-03 16:38:02 +0200328 if (!(s->flags & SF_ERR_MASK))
329 s->flags |= SF_ERR_LOCAL; /* we don't want a real error here */
330 goto return_prx_cond;
331 }
332
333 /*
334 * 3: Maybe we have to copy the original REQURI for the logs ?
335 * Note: we cannot log anymore if the request has been
336 * classified as invalid.
337 */
338 if (unlikely(s->logs.logwait & LW_REQ)) {
339 /* we have a complete HTTP request that we must log */
340 if ((txn->uri = pool_alloc(pool_head_requri)) != NULL) {
Christopher Faulet9768c262018-10-22 09:34:31 +0200341 size_t len;
Christopher Faulete0768eb2018-10-03 16:38:02 +0200342
Christopher Faulet9768c262018-10-22 09:34:31 +0200343 len = htx_fmt_req_line(sl, txn->uri, global.tune.requri_len - 1);
344 txn->uri[len] = 0;
Christopher Faulete0768eb2018-10-03 16:38:02 +0200345
346 if (!(s->logs.logwait &= ~(LW_REQ|LW_INIT)))
347 s->do_log(s);
348 } else {
349 ha_alert("HTTP logging : out of memory.\n");
350 }
351 }
Christopher Faulete0768eb2018-10-03 16:38:02 +0200352
Christopher Faulete0768eb2018-10-03 16:38:02 +0200353 /* if the frontend has "option http-use-proxy-header", we'll check if
354 * we have what looks like a proxied connection instead of a connection,
355 * and in this case set the TX_USE_PX_CONN flag to use Proxy-connection.
356 * Note that this is *not* RFC-compliant, however browsers and proxies
357 * happen to do that despite being non-standard :-(
358 * We consider that a request not beginning with either '/' or '*' is
359 * a proxied connection, which covers both "scheme://location" and
360 * CONNECT ip:port.
361 */
362 if ((sess->fe->options2 & PR_O2_USE_PXHDR) &&
Christopher Faulet9768c262018-10-22 09:34:31 +0200363 *(sl.rq.u.ptr) != '/' && *(sl.rq.u.ptr) != '*')
Christopher Faulete0768eb2018-10-03 16:38:02 +0200364 txn->flags |= TX_USE_PX_CONN;
365
Christopher Faulete0768eb2018-10-03 16:38:02 +0200366 /* 5: we may need to capture headers */
367 if (unlikely((s->logs.logwait & LW_REQHDR) && s->req_cap))
Christopher Faulet9768c262018-10-22 09:34:31 +0200368 htx_capture_headers(htx, s->req_cap, sess->fe->req_cap);
Christopher Faulete0768eb2018-10-03 16:38:02 +0200369
370 /* Until set to anything else, the connection mode is set as Keep-Alive. It will
371 * only change if both the request and the config reference something else.
372 * Option httpclose by itself sets tunnel mode where headers are mangled.
373 * However, if another mode is set, it will affect it (eg: server-close/
374 * keep-alive + httpclose = close). Note that we avoid to redo the same work
375 * if FE and BE have the same settings (common). The method consists in
376 * checking if options changed between the two calls (implying that either
377 * one is non-null, or one of them is non-null and we are there for the first
378 * time.
379 */
Christopher Fauletf2824e62018-10-01 12:12:37 +0200380 if ((sess->fe->options & PR_O_HTTP_MODE) != (s->be->options & PR_O_HTTP_MODE))
Christopher Faulet0f226952018-10-22 09:29:56 +0200381 htx_adjust_conn_mode(s, txn);
Christopher Faulete0768eb2018-10-03 16:38:02 +0200382
383 /* we may have to wait for the request's body */
Christopher Faulet9768c262018-10-22 09:34:31 +0200384 if (s->be->options & PR_O_WREQ_BODY)
Christopher Faulete0768eb2018-10-03 16:38:02 +0200385 req->analysers |= AN_REQ_HTTP_BODY;
386
387 /*
388 * RFC7234#4:
389 * A cache MUST write through requests with methods
390 * that are unsafe (Section 4.2.1 of [RFC7231]) to
391 * the origin server; i.e., a cache is not allowed
392 * to generate a reply to such a request before
393 * having forwarded the request and having received
394 * a corresponding response.
395 *
396 * RFC7231#4.2.1:
397 * Of the request methods defined by this
398 * specification, the GET, HEAD, OPTIONS, and TRACE
399 * methods are defined to be safe.
400 */
401 if (likely(txn->meth == HTTP_METH_GET ||
402 txn->meth == HTTP_METH_HEAD ||
403 txn->meth == HTTP_METH_OPTIONS ||
404 txn->meth == HTTP_METH_TRACE))
405 txn->flags |= TX_CACHEABLE | TX_CACHE_COOK;
406
407 /* end of job, return OK */
408 req->analysers &= ~an_bit;
409 req->analyse_exp = TICK_ETERNITY;
Christopher Faulet9768c262018-10-22 09:34:31 +0200410
Christopher Faulete0768eb2018-10-03 16:38:02 +0200411 return 1;
412
413 return_bad_req:
Christopher Faulet9768c262018-10-22 09:34:31 +0200414 txn->status = 400;
Christopher Faulete0768eb2018-10-03 16:38:02 +0200415 txn->req.err_state = txn->req.msg_state;
416 txn->req.msg_state = HTTP_MSG_ERROR;
Christopher Faulet9768c262018-10-22 09:34:31 +0200417 htx_reply_and_close(s, txn->status, http_error_message(s));
Christopher Faulete0768eb2018-10-03 16:38:02 +0200418 HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_req, 1);
419 if (sess->listener->counters)
420 HA_ATOMIC_ADD(&sess->listener->counters->failed_req, 1);
421
422 return_prx_cond:
423 if (!(s->flags & SF_ERR_MASK))
424 s->flags |= SF_ERR_PRXCOND;
425 if (!(s->flags & SF_FINST_MASK))
426 s->flags |= SF_FINST_R;
427
428 req->analysers &= AN_REQ_FLT_END;
429 req->analyse_exp = TICK_ETERNITY;
430 return 0;
431}
432
433
434/* This stream analyser runs all HTTP request processing which is common to
435 * frontends and backends, which means blocking ACLs, filters, connection-close,
436 * reqadd, stats and redirects. This is performed for the designated proxy.
437 * It returns 1 if the processing can continue on next analysers, or zero if it
438 * either needs more data or wants to immediately abort the request (eg: deny,
439 * error, ...).
440 */
441int htx_process_req_common(struct stream *s, struct channel *req, int an_bit, struct proxy *px)
442{
443 struct session *sess = s->sess;
444 struct http_txn *txn = s->txn;
445 struct http_msg *msg = &txn->req;
446 struct redirect_rule *rule;
447 struct cond_wordlist *wl;
448 enum rule_result verdict;
449 int deny_status = HTTP_ERR_403;
450 struct connection *conn = objt_conn(sess->origin);
451
Christopher Faulet9768c262018-10-22 09:34:31 +0200452 // TODO: Disabled for now
453 req->analyse_exp = TICK_ETERNITY;
454 req->analysers &= ~an_bit;
455 return 1;
456
Christopher Faulete0768eb2018-10-03 16:38:02 +0200457 if (unlikely(msg->msg_state < HTTP_MSG_BODY)) {
458 /* we need more data */
459 goto return_prx_yield;
460 }
461
462 DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
463 now_ms, __FUNCTION__,
464 s,
465 req,
466 req->rex, req->wex,
467 req->flags,
468 ci_data(req),
469 req->analysers);
470
471 /* just in case we have some per-backend tracking */
472 stream_inc_be_http_req_ctr(s);
473
474 /* evaluate http-request rules */
475 if (!LIST_ISEMPTY(&px->http_req_rules)) {
476 verdict = http_req_get_intercept_rule(px, &px->http_req_rules, s, &deny_status);
477
478 switch (verdict) {
479 case HTTP_RULE_RES_YIELD: /* some data miss, call the function later. */
480 goto return_prx_yield;
481
482 case HTTP_RULE_RES_CONT:
483 case HTTP_RULE_RES_STOP: /* nothing to do */
484 break;
485
486 case HTTP_RULE_RES_DENY: /* deny or tarpit */
487 if (txn->flags & TX_CLTARPIT)
488 goto tarpit;
489 goto deny;
490
491 case HTTP_RULE_RES_ABRT: /* abort request, response already sent. Eg: auth */
492 goto return_prx_cond;
493
494 case HTTP_RULE_RES_DONE: /* OK, but terminate request processing (eg: redirect) */
495 goto done;
496
497 case HTTP_RULE_RES_BADREQ: /* failed with a bad request */
498 goto return_bad_req;
499 }
500 }
501
502 if (conn && (conn->flags & CO_FL_EARLY_DATA) &&
503 (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_HANDSHAKE))) {
504 struct hdr_ctx ctx;
505
506 ctx.idx = 0;
507 if (!http_find_header2("Early-Data", strlen("Early-Data"),
508 ci_head(&s->req), &txn->hdr_idx, &ctx)) {
509 if (unlikely(http_header_add_tail2(&txn->req,
510 &txn->hdr_idx, "Early-Data: 1",
511 strlen("Early-Data: 1")) < 0)) {
512 goto return_bad_req;
513 }
514 }
515
516 }
517
518 /* OK at this stage, we know that the request was accepted according to
519 * the http-request rules, we can check for the stats. Note that the
520 * URI is detected *before* the req* rules in order not to be affected
521 * by a possible reqrep, while they are processed *after* so that a
522 * reqdeny can still block them. This clearly needs to change in 1.6!
523 */
524 if (stats_check_uri(&s->si[1], txn, px)) {
525 s->target = &http_stats_applet.obj_type;
526 if (unlikely(!stream_int_register_handler(&s->si[1], objt_applet(s->target)))) {
527 txn->status = 500;
528 s->logs.tv_request = now;
529 http_reply_and_close(s, txn->status, http_error_message(s));
530
531 if (!(s->flags & SF_ERR_MASK))
532 s->flags |= SF_ERR_RESOURCE;
533 goto return_prx_cond;
534 }
535
536 /* parse the whole stats request and extract the relevant information */
537 http_handle_stats(s, req);
538 verdict = http_req_get_intercept_rule(px, &px->uri_auth->http_req_rules, s, &deny_status);
539 /* not all actions implemented: deny, allow, auth */
540
541 if (verdict == HTTP_RULE_RES_DENY) /* stats http-request deny */
542 goto deny;
543
544 if (verdict == HTTP_RULE_RES_ABRT) /* stats auth / stats http-request auth */
545 goto return_prx_cond;
546 }
547
548 /* evaluate the req* rules except reqadd */
549 if (px->req_exp != NULL) {
550 if (apply_filters_to_request(s, req, px) < 0)
551 goto return_bad_req;
552
553 if (txn->flags & TX_CLDENY)
554 goto deny;
555
556 if (txn->flags & TX_CLTARPIT) {
557 deny_status = HTTP_ERR_500;
558 goto tarpit;
559 }
560 }
561
562 /* add request headers from the rule sets in the same order */
563 list_for_each_entry(wl, &px->req_add, list) {
564 if (wl->cond) {
565 int ret = acl_exec_cond(wl->cond, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
566 ret = acl_pass(ret);
567 if (((struct acl_cond *)wl->cond)->pol == ACL_COND_UNLESS)
568 ret = !ret;
569 if (!ret)
570 continue;
571 }
572
573 if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, wl->s, strlen(wl->s)) < 0))
574 goto return_bad_req;
575 }
576
577
578 /* Proceed with the stats now. */
579 if (unlikely(objt_applet(s->target) == &http_stats_applet) ||
580 unlikely(objt_applet(s->target) == &http_cache_applet)) {
581 /* process the stats request now */
582 if (sess->fe == s->be) /* report it if the request was intercepted by the frontend */
583 HA_ATOMIC_ADD(&sess->fe->fe_counters.intercepted_req, 1);
584
585 if (!(s->flags & SF_ERR_MASK)) // this is not really an error but it is
586 s->flags |= SF_ERR_LOCAL; // to mark that it comes from the proxy
587 if (!(s->flags & SF_FINST_MASK))
588 s->flags |= SF_FINST_R;
589
590 /* enable the minimally required analyzers to handle keep-alive and compression on the HTTP response */
591 req->analysers &= (AN_REQ_HTTP_BODY | AN_REQ_FLT_HTTP_HDRS | AN_REQ_FLT_END);
592 req->analysers &= ~AN_REQ_FLT_XFER_DATA;
593 req->analysers |= AN_REQ_HTTP_XFER_BODY;
594 goto done;
595 }
596
597 /* check whether we have some ACLs set to redirect this request */
598 list_for_each_entry(rule, &px->redirect_rules, list) {
599 if (rule->cond) {
600 int ret;
601
602 ret = acl_exec_cond(rule->cond, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
603 ret = acl_pass(ret);
604 if (rule->cond->pol == ACL_COND_UNLESS)
605 ret = !ret;
606 if (!ret)
607 continue;
608 }
Christopher Fauletf2824e62018-10-01 12:12:37 +0200609 if (!htx_apply_redirect_rule(rule, s, txn))
Christopher Faulete0768eb2018-10-03 16:38:02 +0200610 goto return_bad_req;
611 goto done;
612 }
613
614 /* POST requests may be accompanied with an "Expect: 100-Continue" header.
615 * If this happens, then the data will not come immediately, so we must
616 * send all what we have without waiting. Note that due to the small gain
617 * in waiting for the body of the request, it's easier to simply put the
618 * CF_SEND_DONTWAIT flag any time. It's a one-shot flag so it will remove
619 * itself once used.
620 */
621 req->flags |= CF_SEND_DONTWAIT;
622
623 done: /* done with this analyser, continue with next ones that the calling
624 * points will have set, if any.
625 */
626 req->analyse_exp = TICK_ETERNITY;
627 done_without_exp: /* done with this analyser, but dont reset the analyse_exp. */
628 req->analysers &= ~an_bit;
629 return 1;
630
631 tarpit:
632 /* Allow cookie logging
633 */
634 if (s->be->cookie_name || sess->fe->capture_name)
635 manage_client_side_cookies(s, req);
636
637 /* When a connection is tarpitted, we use the tarpit timeout,
638 * which may be the same as the connect timeout if unspecified.
639 * If unset, then set it to zero because we really want it to
640 * eventually expire. We build the tarpit as an analyser.
641 */
642 channel_erase(&s->req);
643
644 /* wipe the request out so that we can drop the connection early
645 * if the client closes first.
646 */
647 channel_dont_connect(req);
648
649 txn->status = http_err_codes[deny_status];
650
651 req->analysers &= AN_REQ_FLT_END; /* remove switching rules etc... */
652 req->analysers |= AN_REQ_HTTP_TARPIT;
653 req->analyse_exp = tick_add_ifset(now_ms, s->be->timeout.tarpit);
654 if (!req->analyse_exp)
655 req->analyse_exp = tick_add(now_ms, 0);
656 stream_inc_http_err_ctr(s);
657 HA_ATOMIC_ADD(&sess->fe->fe_counters.denied_req, 1);
658 if (sess->fe != s->be)
659 HA_ATOMIC_ADD(&s->be->be_counters.denied_req, 1);
660 if (sess->listener->counters)
661 HA_ATOMIC_ADD(&sess->listener->counters->denied_req, 1);
662 goto done_without_exp;
663
664 deny: /* this request was blocked (denied) */
665
666 /* Allow cookie logging
667 */
668 if (s->be->cookie_name || sess->fe->capture_name)
669 manage_client_side_cookies(s, req);
670
671 txn->flags |= TX_CLDENY;
672 txn->status = http_err_codes[deny_status];
673 s->logs.tv_request = now;
674 http_reply_and_close(s, txn->status, http_error_message(s));
675 stream_inc_http_err_ctr(s);
676 HA_ATOMIC_ADD(&sess->fe->fe_counters.denied_req, 1);
677 if (sess->fe != s->be)
678 HA_ATOMIC_ADD(&s->be->be_counters.denied_req, 1);
679 if (sess->listener->counters)
680 HA_ATOMIC_ADD(&sess->listener->counters->denied_req, 1);
681 goto return_prx_cond;
682
683 return_bad_req:
684 /* We centralize bad requests processing here */
685 if (unlikely(msg->msg_state == HTTP_MSG_ERROR) || msg->err_pos >= 0) {
686 /* we detected a parsing error. We want to archive this request
687 * in the dedicated proxy area for later troubleshooting.
688 */
689 http_capture_bad_message(sess->fe, s, msg, msg->err_state, sess->fe);
690 }
691
692 txn->req.err_state = txn->req.msg_state;
693 txn->req.msg_state = HTTP_MSG_ERROR;
694 txn->status = 400;
695 http_reply_and_close(s, txn->status, http_error_message(s));
696
697 HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_req, 1);
698 if (sess->listener->counters)
699 HA_ATOMIC_ADD(&sess->listener->counters->failed_req, 1);
700
701 return_prx_cond:
702 if (!(s->flags & SF_ERR_MASK))
703 s->flags |= SF_ERR_PRXCOND;
704 if (!(s->flags & SF_FINST_MASK))
705 s->flags |= SF_FINST_R;
706
707 req->analysers &= AN_REQ_FLT_END;
708 req->analyse_exp = TICK_ETERNITY;
709 return 0;
710
711 return_prx_yield:
712 channel_dont_connect(req);
713 return 0;
714}
715
716/* This function performs all the processing enabled for the current request.
717 * It returns 1 if the processing can continue on next analysers, or zero if it
718 * needs more data, encounters an error, or wants to immediately abort the
719 * request. It relies on buffers flags, and updates s->req.analysers.
720 */
721int htx_process_request(struct stream *s, struct channel *req, int an_bit)
722{
723 struct session *sess = s->sess;
724 struct http_txn *txn = s->txn;
725 struct http_msg *msg = &txn->req;
726 struct connection *cli_conn = objt_conn(strm_sess(s)->origin);
727
Christopher Faulet9768c262018-10-22 09:34:31 +0200728 // TODO: Disabled for now
729 req->analysers &= ~AN_REQ_FLT_XFER_DATA;
730 req->analysers |= AN_REQ_HTTP_XFER_BODY;
731 req->analyse_exp = TICK_ETERNITY;
732 req->analysers &= ~an_bit;
733 return 1;
734
Christopher Faulete0768eb2018-10-03 16:38:02 +0200735 if (unlikely(msg->msg_state < HTTP_MSG_BODY)) {
736 /* we need more data */
737 channel_dont_connect(req);
738 return 0;
739 }
740
741 DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
742 now_ms, __FUNCTION__,
743 s,
744 req,
745 req->rex, req->wex,
746 req->flags,
747 ci_data(req),
748 req->analysers);
749
750 /*
751 * Right now, we know that we have processed the entire headers
752 * and that unwanted requests have been filtered out. We can do
753 * whatever we want with the remaining request. Also, now we
754 * may have separate values for ->fe, ->be.
755 */
756
757 /*
758 * If HTTP PROXY is set we simply get remote server address parsing
759 * incoming request. Note that this requires that a connection is
760 * allocated on the server side.
761 */
762 if ((s->be->options & PR_O_HTTP_PROXY) && !(s->flags & SF_ADDR_SET)) {
763 struct connection *conn;
764 char *path;
765
766 /* Note that for now we don't reuse existing proxy connections */
767 if (unlikely((conn = cs_conn(si_alloc_cs(&s->si[1], NULL))) == NULL)) {
768 txn->req.err_state = txn->req.msg_state;
769 txn->req.msg_state = HTTP_MSG_ERROR;
770 txn->status = 500;
771 req->analysers &= AN_REQ_FLT_END;
772 http_reply_and_close(s, txn->status, http_error_message(s));
773
774 if (!(s->flags & SF_ERR_MASK))
775 s->flags |= SF_ERR_RESOURCE;
776 if (!(s->flags & SF_FINST_MASK))
777 s->flags |= SF_FINST_R;
778
779 return 0;
780 }
781
782 path = http_txn_get_path(txn);
783 if (url2sa(ci_head(req) + msg->sl.rq.u,
784 path ? path - (ci_head(req) + msg->sl.rq.u) : msg->sl.rq.u_l,
785 &conn->addr.to, NULL) == -1)
786 goto return_bad_req;
787
788 /* if the path was found, we have to remove everything between
789 * ci_head(req) + msg->sl.rq.u and path (excluded). If it was not
790 * found, we need to replace from ci_head(req) + msg->sl.rq.u for
791 * u_l characters by a single "/".
792 */
793 if (path) {
794 char *cur_ptr = ci_head(req);
795 char *cur_end = cur_ptr + txn->req.sl.rq.l;
796 int delta;
797
798 delta = b_rep_blk(&req->buf, cur_ptr + msg->sl.rq.u, path, NULL, 0);
799 http_msg_move_end(&txn->req, delta);
800 cur_end += delta;
801 if (http_parse_reqline(&txn->req, HTTP_MSG_RQMETH, cur_ptr, cur_end + 1, NULL, NULL) == NULL)
802 goto return_bad_req;
803 }
804 else {
805 char *cur_ptr = ci_head(req);
806 char *cur_end = cur_ptr + txn->req.sl.rq.l;
807 int delta;
808
809 delta = b_rep_blk(&req->buf, cur_ptr + msg->sl.rq.u,
810 cur_ptr + msg->sl.rq.u + msg->sl.rq.u_l, "/", 1);
811 http_msg_move_end(&txn->req, delta);
812 cur_end += delta;
813 if (http_parse_reqline(&txn->req, HTTP_MSG_RQMETH, cur_ptr, cur_end + 1, NULL, NULL) == NULL)
814 goto return_bad_req;
815 }
816 }
817
818 /*
819 * 7: Now we can work with the cookies.
820 * Note that doing so might move headers in the request, but
821 * the fields will stay coherent and the URI will not move.
822 * This should only be performed in the backend.
823 */
824 if (s->be->cookie_name || sess->fe->capture_name)
825 manage_client_side_cookies(s, req);
826
827 /* add unique-id if "header-unique-id" is specified */
828
829 if (!LIST_ISEMPTY(&sess->fe->format_unique_id) && !s->unique_id) {
830 if ((s->unique_id = pool_alloc(pool_head_uniqueid)) == NULL)
831 goto return_bad_req;
832 s->unique_id[0] = '\0';
833 build_logline(s, s->unique_id, UNIQUEID_LEN, &sess->fe->format_unique_id);
834 }
835
836 if (sess->fe->header_unique_id && s->unique_id) {
837 if (chunk_printf(&trash, "%s: %s", sess->fe->header_unique_id, s->unique_id) < 0)
838 goto return_bad_req;
839 if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash.area, trash.data) < 0))
840 goto return_bad_req;
841 }
842
843 /*
844 * 9: add X-Forwarded-For if either the frontend or the backend
845 * asks for it.
846 */
847 if ((sess->fe->options | s->be->options) & PR_O_FWDFOR) {
848 struct hdr_ctx ctx = { .idx = 0 };
849 if (!((sess->fe->options | s->be->options) & PR_O_FF_ALWAYS) &&
850 http_find_header2(s->be->fwdfor_hdr_len ? s->be->fwdfor_hdr_name : sess->fe->fwdfor_hdr_name,
851 s->be->fwdfor_hdr_len ? s->be->fwdfor_hdr_len : sess->fe->fwdfor_hdr_len,
852 ci_head(req), &txn->hdr_idx, &ctx)) {
853 /* The header is set to be added only if none is present
854 * and we found it, so don't do anything.
855 */
856 }
857 else if (cli_conn && cli_conn->addr.from.ss_family == AF_INET) {
858 /* Add an X-Forwarded-For header unless the source IP is
859 * in the 'except' network range.
860 */
861 if ((!sess->fe->except_mask.s_addr ||
862 (((struct sockaddr_in *)&cli_conn->addr.from)->sin_addr.s_addr & sess->fe->except_mask.s_addr)
863 != sess->fe->except_net.s_addr) &&
864 (!s->be->except_mask.s_addr ||
865 (((struct sockaddr_in *)&cli_conn->addr.from)->sin_addr.s_addr & s->be->except_mask.s_addr)
866 != s->be->except_net.s_addr)) {
867 int len;
868 unsigned char *pn;
869 pn = (unsigned char *)&((struct sockaddr_in *)&cli_conn->addr.from)->sin_addr;
870
871 /* Note: we rely on the backend to get the header name to be used for
872 * x-forwarded-for, because the header is really meant for the backends.
873 * However, if the backend did not specify any option, we have to rely
874 * on the frontend's header name.
875 */
876 if (s->be->fwdfor_hdr_len) {
877 len = s->be->fwdfor_hdr_len;
878 memcpy(trash.area,
879 s->be->fwdfor_hdr_name, len);
880 } else {
881 len = sess->fe->fwdfor_hdr_len;
882 memcpy(trash.area,
883 sess->fe->fwdfor_hdr_name, len);
884 }
885 len += snprintf(trash.area + len,
886 trash.size - len,
887 ": %d.%d.%d.%d", pn[0], pn[1],
888 pn[2], pn[3]);
889
890 if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash.area, len) < 0))
891 goto return_bad_req;
892 }
893 }
894 else if (cli_conn && cli_conn->addr.from.ss_family == AF_INET6) {
895 /* FIXME: for the sake of completeness, we should also support
896 * 'except' here, although it is mostly useless in this case.
897 */
898 int len;
899 char pn[INET6_ADDRSTRLEN];
900 inet_ntop(AF_INET6,
901 (const void *)&((struct sockaddr_in6 *)(&cli_conn->addr.from))->sin6_addr,
902 pn, sizeof(pn));
903
904 /* Note: we rely on the backend to get the header name to be used for
905 * x-forwarded-for, because the header is really meant for the backends.
906 * However, if the backend did not specify any option, we have to rely
907 * on the frontend's header name.
908 */
909 if (s->be->fwdfor_hdr_len) {
910 len = s->be->fwdfor_hdr_len;
911 memcpy(trash.area, s->be->fwdfor_hdr_name,
912 len);
913 } else {
914 len = sess->fe->fwdfor_hdr_len;
915 memcpy(trash.area, sess->fe->fwdfor_hdr_name,
916 len);
917 }
918 len += snprintf(trash.area + len, trash.size - len,
919 ": %s", pn);
920
921 if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash.area, len) < 0))
922 goto return_bad_req;
923 }
924 }
925
926 /*
927 * 10: add X-Original-To if either the frontend or the backend
928 * asks for it.
929 */
930 if ((sess->fe->options | s->be->options) & PR_O_ORGTO) {
931
932 /* FIXME: don't know if IPv6 can handle that case too. */
933 if (cli_conn && cli_conn->addr.from.ss_family == AF_INET) {
934 /* Add an X-Original-To header unless the destination IP is
935 * in the 'except' network range.
936 */
937 conn_get_to_addr(cli_conn);
938
939 if (cli_conn->addr.to.ss_family == AF_INET &&
940 ((!sess->fe->except_mask_to.s_addr ||
941 (((struct sockaddr_in *)&cli_conn->addr.to)->sin_addr.s_addr & sess->fe->except_mask_to.s_addr)
942 != sess->fe->except_to.s_addr) &&
943 (!s->be->except_mask_to.s_addr ||
944 (((struct sockaddr_in *)&cli_conn->addr.to)->sin_addr.s_addr & s->be->except_mask_to.s_addr)
945 != s->be->except_to.s_addr))) {
946 int len;
947 unsigned char *pn;
948 pn = (unsigned char *)&((struct sockaddr_in *)&cli_conn->addr.to)->sin_addr;
949
950 /* Note: we rely on the backend to get the header name to be used for
951 * x-original-to, because the header is really meant for the backends.
952 * However, if the backend did not specify any option, we have to rely
953 * on the frontend's header name.
954 */
955 if (s->be->orgto_hdr_len) {
956 len = s->be->orgto_hdr_len;
957 memcpy(trash.area,
958 s->be->orgto_hdr_name, len);
959 } else {
960 len = sess->fe->orgto_hdr_len;
961 memcpy(trash.area,
962 sess->fe->orgto_hdr_name, len);
963 }
964 len += snprintf(trash.area + len,
965 trash.size - len,
966 ": %d.%d.%d.%d", pn[0], pn[1],
967 pn[2], pn[3]);
968
969 if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash.area, len) < 0))
970 goto return_bad_req;
971 }
972 }
Christopher Faulete0768eb2018-10-03 16:38:02 +0200973 }
974
Christopher Faulete0768eb2018-10-03 16:38:02 +0200975 /* If we have no server assigned yet and we're balancing on url_param
976 * with a POST request, we may be interested in checking the body for
977 * that parameter. This will be done in another analyser.
978 */
979 if (!(s->flags & (SF_ASSIGNED|SF_DIRECT)) &&
980 s->txn->meth == HTTP_METH_POST && s->be->url_param_name != NULL &&
981 (msg->flags & (HTTP_MSGF_CNT_LEN|HTTP_MSGF_TE_CHNK))) {
982 channel_dont_connect(req);
983 req->analysers |= AN_REQ_HTTP_BODY;
984 }
985
986 req->analysers &= ~AN_REQ_FLT_XFER_DATA;
987 req->analysers |= AN_REQ_HTTP_XFER_BODY;
988#ifdef TCP_QUICKACK
989 /* We expect some data from the client. Unless we know for sure
990 * we already have a full request, we have to re-enable quick-ack
991 * in case we previously disabled it, otherwise we might cause
992 * the client to delay further data.
993 */
994 if ((sess->listener->options & LI_O_NOQUICKACK) &&
995 cli_conn && conn_ctrl_ready(cli_conn) &&
996 ((msg->flags & HTTP_MSGF_TE_CHNK) ||
997 (msg->body_len > ci_data(req) - txn->req.eoh - 2)))
998 setsockopt(cli_conn->handle.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
999#endif
1000
1001 /*************************************************************
1002 * OK, that's finished for the headers. We have done what we *
1003 * could. Let's switch to the DATA state. *
1004 ************************************************************/
1005 req->analyse_exp = TICK_ETERNITY;
1006 req->analysers &= ~an_bit;
1007
1008 s->logs.tv_request = now;
1009 /* OK let's go on with the BODY now */
1010 return 1;
1011
1012 return_bad_req: /* let's centralize all bad requests */
1013 if (unlikely(msg->msg_state == HTTP_MSG_ERROR) || msg->err_pos >= 0) {
1014 /* we detected a parsing error. We want to archive this request
1015 * in the dedicated proxy area for later troubleshooting.
1016 */
1017 http_capture_bad_message(sess->fe, s, msg, msg->err_state, sess->fe);
1018 }
1019
1020 txn->req.err_state = txn->req.msg_state;
1021 txn->req.msg_state = HTTP_MSG_ERROR;
1022 txn->status = 400;
1023 req->analysers &= AN_REQ_FLT_END;
1024 http_reply_and_close(s, txn->status, http_error_message(s));
1025
1026 HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_req, 1);
1027 if (sess->listener->counters)
1028 HA_ATOMIC_ADD(&sess->listener->counters->failed_req, 1);
1029
1030 if (!(s->flags & SF_ERR_MASK))
1031 s->flags |= SF_ERR_PRXCOND;
1032 if (!(s->flags & SF_FINST_MASK))
1033 s->flags |= SF_FINST_R;
1034 return 0;
1035}
1036
1037/* This function is an analyser which processes the HTTP tarpit. It always
1038 * returns zero, at the beginning because it prevents any other processing
1039 * from occurring, and at the end because it terminates the request.
1040 */
1041int htx_process_tarpit(struct stream *s, struct channel *req, int an_bit)
1042{
1043 struct http_txn *txn = s->txn;
1044
Christopher Faulet9768c262018-10-22 09:34:31 +02001045 // TODO: Disabled for now
1046 req->analyse_exp = TICK_ETERNITY;
1047 req->analysers &= ~an_bit;
1048 return 1;
1049
Christopher Faulete0768eb2018-10-03 16:38:02 +02001050 /* This connection is being tarpitted. The CLIENT side has
1051 * already set the connect expiration date to the right
1052 * timeout. We just have to check that the client is still
1053 * there and that the timeout has not expired.
1054 */
1055 channel_dont_connect(req);
1056 if ((req->flags & (CF_SHUTR|CF_READ_ERROR)) == 0 &&
1057 !tick_is_expired(req->analyse_exp, now_ms))
1058 return 0;
1059
1060 /* We will set the queue timer to the time spent, just for
1061 * logging purposes. We fake a 500 server error, so that the
1062 * attacker will not suspect his connection has been tarpitted.
1063 * It will not cause trouble to the logs because we can exclude
1064 * the tarpitted connections by filtering on the 'PT' status flags.
1065 */
1066 s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
1067
1068 if (!(req->flags & CF_READ_ERROR))
1069 http_reply_and_close(s, txn->status, http_error_message(s));
1070
1071 req->analysers &= AN_REQ_FLT_END;
1072 req->analyse_exp = TICK_ETERNITY;
1073
1074 if (!(s->flags & SF_ERR_MASK))
1075 s->flags |= SF_ERR_PRXCOND;
1076 if (!(s->flags & SF_FINST_MASK))
1077 s->flags |= SF_FINST_T;
1078 return 0;
1079}
1080
1081/* This function is an analyser which waits for the HTTP request body. It waits
1082 * for either the buffer to be full, or the full advertised contents to have
1083 * reached the buffer. It must only be called after the standard HTTP request
1084 * processing has occurred, because it expects the request to be parsed and will
1085 * look for the Expect header. It may send a 100-Continue interim response. It
1086 * takes in input any state starting from HTTP_MSG_BODY and leaves with one of
1087 * HTTP_MSG_CHK_SIZE, HTTP_MSG_DATA or HTTP_MSG_TRAILERS. It returns zero if it
1088 * needs to read more data, or 1 once it has completed its analysis.
1089 */
1090int htx_wait_for_request_body(struct stream *s, struct channel *req, int an_bit)
1091{
1092 struct session *sess = s->sess;
1093 struct http_txn *txn = s->txn;
1094 struct http_msg *msg = &s->txn->req;
1095
Christopher Faulet9768c262018-10-22 09:34:31 +02001096 // TODO: Disabled for now
1097 req->analyse_exp = TICK_ETERNITY;
1098 req->analysers &= ~an_bit;
1099 return 1;
1100
Christopher Faulete0768eb2018-10-03 16:38:02 +02001101 /* We have to parse the HTTP request body to find any required data.
1102 * "balance url_param check_post" should have been the only way to get
1103 * into this. We were brought here after HTTP header analysis, so all
1104 * related structures are ready.
1105 */
1106
1107 if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
1108 /* This is the first call */
1109 if (msg->msg_state < HTTP_MSG_BODY)
1110 goto missing_data;
1111
1112 if (msg->msg_state < HTTP_MSG_100_SENT) {
1113 /* If we have HTTP/1.1 and Expect: 100-continue, then we must
1114 * send an HTTP/1.1 100 Continue intermediate response.
1115 */
1116 if (msg->flags & HTTP_MSGF_VER_11) {
1117 struct hdr_ctx ctx;
1118 ctx.idx = 0;
1119 /* Expect is allowed in 1.1, look for it */
1120 if (http_find_header2("Expect", 6, ci_head(req), &txn->hdr_idx, &ctx) &&
1121 unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val, "100-continue", 12) == 0)) {
1122 co_inject(&s->res, HTTP_100.ptr, HTTP_100.len);
1123 http_remove_header2(&txn->req, &txn->hdr_idx, &ctx);
1124 }
1125 }
1126 msg->msg_state = HTTP_MSG_100_SENT;
1127 }
1128
1129 /* we have msg->sov which points to the first byte of message body.
1130 * ci_head(req) still points to the beginning of the message. We
1131 * must save the body in msg->next because it survives buffer
1132 * re-alignments.
1133 */
1134 msg->next = msg->sov;
1135
1136 if (msg->flags & HTTP_MSGF_TE_CHNK)
1137 msg->msg_state = HTTP_MSG_CHUNK_SIZE;
1138 else
1139 msg->msg_state = HTTP_MSG_DATA;
1140 }
1141
1142 if (!(msg->flags & HTTP_MSGF_TE_CHNK)) {
1143 /* We're in content-length mode, we just have to wait for enough data. */
1144 if (http_body_bytes(msg) < msg->body_len)
1145 goto missing_data;
1146
1147 /* OK we have everything we need now */
1148 goto http_end;
1149 }
1150
1151 /* OK here we're parsing a chunked-encoded message */
1152
1153 if (msg->msg_state == HTTP_MSG_CHUNK_SIZE) {
1154 /* read the chunk size and assign it to ->chunk_len, then
1155 * set ->sov and ->next to point to the body and switch to DATA or
1156 * TRAILERS state.
1157 */
1158 unsigned int chunk;
1159 int ret = h1_parse_chunk_size(&req->buf, co_data(req) + msg->next, c_data(req), &chunk);
1160
1161 if (!ret)
1162 goto missing_data;
1163 else if (ret < 0) {
1164 msg->err_pos = ci_data(req) + ret;
1165 if (msg->err_pos < 0)
1166 msg->err_pos += req->buf.size;
1167 stream_inc_http_err_ctr(s);
1168 goto return_bad_req;
1169 }
1170
1171 msg->chunk_len = chunk;
1172 msg->body_len += chunk;
1173
1174 msg->sol = ret;
1175 msg->next += ret;
1176 msg->msg_state = msg->chunk_len ? HTTP_MSG_DATA : HTTP_MSG_TRAILERS;
1177 }
1178
1179 /* Now we're in HTTP_MSG_DATA or HTTP_MSG_TRAILERS state.
1180 * We have the first data byte is in msg->sov + msg->sol. We're waiting
1181 * for at least a whole chunk or the whole content length bytes after
1182 * msg->sov + msg->sol.
1183 */
1184 if (msg->msg_state == HTTP_MSG_TRAILERS)
1185 goto http_end;
1186
1187 if (http_body_bytes(msg) >= msg->body_len) /* we have enough bytes now */
1188 goto http_end;
1189
1190 missing_data:
1191 /* we get here if we need to wait for more data. If the buffer is full,
1192 * we have the maximum we can expect.
1193 */
1194 if (channel_full(req, global.tune.maxrewrite))
1195 goto http_end;
1196
1197 if ((req->flags & CF_READ_TIMEOUT) || tick_is_expired(req->analyse_exp, now_ms)) {
1198 txn->status = 408;
1199 http_reply_and_close(s, txn->status, http_error_message(s));
1200
1201 if (!(s->flags & SF_ERR_MASK))
1202 s->flags |= SF_ERR_CLITO;
1203 if (!(s->flags & SF_FINST_MASK))
1204 s->flags |= SF_FINST_D;
1205 goto return_err_msg;
1206 }
1207
1208 /* we get here if we need to wait for more data */
1209 if (!(req->flags & (CF_SHUTR | CF_READ_ERROR))) {
1210 /* Not enough data. We'll re-use the http-request
1211 * timeout here. Ideally, we should set the timeout
1212 * relative to the accept() date. We just set the
1213 * request timeout once at the beginning of the
1214 * request.
1215 */
1216 channel_dont_connect(req);
1217 if (!tick_isset(req->analyse_exp))
1218 req->analyse_exp = tick_add_ifset(now_ms, s->be->timeout.httpreq);
1219 return 0;
1220 }
1221
1222 http_end:
1223 /* The situation will not evolve, so let's give up on the analysis. */
1224 s->logs.tv_request = now; /* update the request timer to reflect full request */
1225 req->analysers &= ~an_bit;
1226 req->analyse_exp = TICK_ETERNITY;
1227 return 1;
1228
1229 return_bad_req: /* let's centralize all bad requests */
1230 txn->req.err_state = txn->req.msg_state;
1231 txn->req.msg_state = HTTP_MSG_ERROR;
1232 txn->status = 400;
1233 http_reply_and_close(s, txn->status, http_error_message(s));
1234
1235 if (!(s->flags & SF_ERR_MASK))
1236 s->flags |= SF_ERR_PRXCOND;
1237 if (!(s->flags & SF_FINST_MASK))
1238 s->flags |= SF_FINST_R;
1239
1240 return_err_msg:
1241 req->analysers &= AN_REQ_FLT_END;
1242 HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_req, 1);
1243 if (sess->listener->counters)
1244 HA_ATOMIC_ADD(&sess->listener->counters->failed_req, 1);
1245 return 0;
1246}
1247
1248/* This function is an analyser which forwards request body (including chunk
1249 * sizes if any). It is called as soon as we must forward, even if we forward
1250 * zero byte. The only situation where it must not be called is when we're in
1251 * tunnel mode and we want to forward till the close. It's used both to forward
1252 * remaining data and to resync after end of body. It expects the msg_state to
1253 * be between MSG_BODY and MSG_DONE (inclusive). It returns zero if it needs to
1254 * read more data, or 1 once we can go on with next request or end the stream.
1255 * When in MSG_DATA or MSG_TRAILERS, it will automatically forward chunk_len
1256 * bytes of pending data + the headers if not already done.
1257 */
1258int htx_request_forward_body(struct stream *s, struct channel *req, int an_bit)
1259{
1260 struct session *sess = s->sess;
1261 struct http_txn *txn = s->txn;
Christopher Faulet9768c262018-10-22 09:34:31 +02001262 struct http_msg *msg = &txn->req;
1263 struct htx *htx;
1264 //int ret;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001265
1266 DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
1267 now_ms, __FUNCTION__,
1268 s,
1269 req,
1270 req->rex, req->wex,
1271 req->flags,
1272 ci_data(req),
1273 req->analysers);
1274
Christopher Faulet9768c262018-10-22 09:34:31 +02001275 htx = htx_from_buf(&req->buf);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001276
1277 if ((req->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) ||
1278 ((req->flags & CF_SHUTW) && (req->to_forward || co_data(req)))) {
1279 /* Output closed while we were sending data. We must abort and
1280 * wake the other side up.
1281 */
1282 msg->err_state = msg->msg_state;
1283 msg->msg_state = HTTP_MSG_ERROR;
Christopher Fauletf2824e62018-10-01 12:12:37 +02001284 htx_end_request(s);
1285 htx_end_response(s);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001286 return 1;
1287 }
1288
1289 /* Note that we don't have to send 100-continue back because we don't
1290 * need the data to complete our job, and it's up to the server to
1291 * decide whether to return 100, 417 or anything else in return of
1292 * an "Expect: 100-continue" header.
1293 */
Christopher Faulet9768c262018-10-22 09:34:31 +02001294 if (msg->msg_state == HTTP_MSG_BODY)
1295 msg->msg_state = HTTP_MSG_DATA;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001296
1297 /* Some post-connect processing might want us to refrain from starting to
1298 * forward data. Currently, the only reason for this is "balance url_param"
1299 * whichs need to parse/process the request after we've enabled forwarding.
1300 */
1301 if (unlikely(msg->flags & HTTP_MSGF_WAIT_CONN)) {
1302 if (!(s->res.flags & CF_READ_ATTACHED)) {
1303 channel_auto_connect(req);
1304 req->flags |= CF_WAKE_CONNECT;
1305 channel_dont_close(req); /* don't fail on early shutr */
1306 goto waiting;
1307 }
1308 msg->flags &= ~HTTP_MSGF_WAIT_CONN;
1309 }
1310
1311 /* in most states, we should abort in case of early close */
1312 channel_auto_close(req);
1313
1314 if (req->to_forward) {
1315 /* We can't process the buffer's contents yet */
1316 req->flags |= CF_WAKE_WRITE;
1317 goto missing_data_or_waiting;
1318 }
1319
Christopher Faulet9768c262018-10-22 09:34:31 +02001320 if (msg->msg_state >= HTTP_MSG_DONE)
1321 goto done;
1322
1323 /* Forward all input data. We get it by removing all outgoing data not
1324 * forwarded yet from HTX data size.
1325 */
1326 c_adv(req, htx->data - co_data(req));
1327
1328 /* To let the function channel_forward work as expected we must update
1329 * the channel's buffer to pretend there is no more input data. The
1330 * right length is then restored. We must do that, because when an HTX
1331 * message is stored into a buffer, it appears as full.
1332 */
1333 b_set_data(&req->buf, co_data(req));
1334 if (htx->extra != ULLONG_MAX)
1335 htx->extra -= channel_forward(req, htx->extra);
1336 b_set_data(&req->buf, b_size(&req->buf));
Christopher Faulete0768eb2018-10-03 16:38:02 +02001337
Christopher Faulet9768c262018-10-22 09:34:31 +02001338 /* Check if the end-of-message is reached and if so, switch the message
1339 * in HTTP_MSG_DONE state.
1340 */
1341 if (htx_get_tail_type(htx) != HTX_BLK_EOM)
1342 goto missing_data_or_waiting;
1343
1344 msg->msg_state = HTTP_MSG_DONE;
1345
1346 done:
Christopher Faulete0768eb2018-10-03 16:38:02 +02001347 /* other states, DONE...TUNNEL */
1348 /* we don't want to forward closes on DONE except in tunnel mode. */
1349 if ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN)
1350 channel_dont_close(req);
1351
Christopher Fauletf2824e62018-10-01 12:12:37 +02001352 htx_end_request(s);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001353 if (!(req->analysers & an_bit)) {
Christopher Fauletf2824e62018-10-01 12:12:37 +02001354 htx_end_response(s);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001355 if (unlikely(msg->msg_state == HTTP_MSG_ERROR)) {
1356 if (req->flags & CF_SHUTW) {
1357 /* request errors are most likely due to the
1358 * server aborting the transfer. */
1359 goto aborted_xfer;
1360 }
Christopher Faulete0768eb2018-10-03 16:38:02 +02001361 goto return_bad_req;
1362 }
1363 return 1;
1364 }
1365
1366 /* If "option abortonclose" is set on the backend, we want to monitor
1367 * the client's connection and forward any shutdown notification to the
1368 * server, which will decide whether to close or to go on processing the
1369 * request. We only do that in tunnel mode, and not in other modes since
1370 * it can be abused to exhaust source ports. */
1371 if ((s->be->options & PR_O_ABRT_CLOSE) && !(s->si[0].flags & SI_FL_CLEAN_ABRT)) {
1372 channel_auto_read(req);
1373 if ((req->flags & (CF_SHUTR|CF_READ_NULL)) &&
1374 ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN))
1375 s->si[1].flags |= SI_FL_NOLINGER;
1376 channel_auto_close(req);
1377 }
1378 else if (s->txn->meth == HTTP_METH_POST) {
1379 /* POST requests may require to read extra CRLF sent by broken
1380 * browsers and which could cause an RST to be sent upon close
1381 * on some systems (eg: Linux). */
1382 channel_auto_read(req);
1383 }
1384 return 0;
1385
1386 missing_data_or_waiting:
1387 /* stop waiting for data if the input is closed before the end */
Christopher Faulet9768c262018-10-22 09:34:31 +02001388 if (msg->msg_state < HTTP_MSG_DONE && req->flags & CF_SHUTR) {
Christopher Faulete0768eb2018-10-03 16:38:02 +02001389 if (!(s->flags & SF_ERR_MASK))
1390 s->flags |= SF_ERR_CLICL;
1391 if (!(s->flags & SF_FINST_MASK)) {
1392 if (txn->rsp.msg_state < HTTP_MSG_ERROR)
1393 s->flags |= SF_FINST_H;
1394 else
1395 s->flags |= SF_FINST_D;
1396 }
1397
1398 HA_ATOMIC_ADD(&sess->fe->fe_counters.cli_aborts, 1);
1399 HA_ATOMIC_ADD(&s->be->be_counters.cli_aborts, 1);
1400 if (objt_server(s->target))
1401 HA_ATOMIC_ADD(&objt_server(s->target)->counters.cli_aborts, 1);
1402
1403 goto return_bad_req_stats_ok;
1404 }
1405
1406 waiting:
1407 /* waiting for the last bits to leave the buffer */
1408 if (req->flags & CF_SHUTW)
1409 goto aborted_xfer;
1410
Christopher Faulet9768c262018-10-22 09:34:31 +02001411
Christopher Faulete0768eb2018-10-03 16:38:02 +02001412 /* When TE: chunked is used, we need to get there again to parse remaining
1413 * chunks even if the client has closed, so we don't want to set CF_DONTCLOSE.
1414 * And when content-length is used, we never want to let the possible
1415 * shutdown be forwarded to the other side, as the state machine will
1416 * take care of it once the client responds. It's also important to
1417 * prevent TIME_WAITs from accumulating on the backend side, and for
1418 * HTTP/2 where the last frame comes with a shutdown.
1419 */
Christopher Faulet9768c262018-10-22 09:34:31 +02001420 if (msg->flags & HTTP_MSGF_XFER_LEN)
Christopher Faulete0768eb2018-10-03 16:38:02 +02001421 channel_dont_close(req);
1422
Christopher Faulet9768c262018-10-22 09:34:31 +02001423#if 0 // FIXME [Cf]: Probably not required now, but I need more time to think
1424 // about if
1425
Christopher Faulete0768eb2018-10-03 16:38:02 +02001426 /* We know that more data are expected, but we couldn't send more that
1427 * what we did. So we always set the CF_EXPECT_MORE flag so that the
1428 * system knows it must not set a PUSH on this first part. Interactive
1429 * modes are already handled by the stream sock layer. We must not do
1430 * this in content-length mode because it could present the MSG_MORE
1431 * flag with the last block of forwarded data, which would cause an
1432 * additional delay to be observed by the receiver.
1433 */
1434 if (msg->flags & HTTP_MSGF_TE_CHNK)
1435 req->flags |= CF_EXPECT_MORE;
Christopher Faulet9768c262018-10-22 09:34:31 +02001436#endif
Christopher Faulete0768eb2018-10-03 16:38:02 +02001437
1438 return 0;
1439
1440 return_bad_req: /* let's centralize all bad requests */
1441 HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_req, 1);
1442 if (sess->listener->counters)
1443 HA_ATOMIC_ADD(&sess->listener->counters->failed_req, 1);
1444
1445 return_bad_req_stats_ok:
1446 txn->req.err_state = txn->req.msg_state;
1447 txn->req.msg_state = HTTP_MSG_ERROR;
Christopher Faulet9768c262018-10-22 09:34:31 +02001448 if (txn->status > 0) {
Christopher Faulete0768eb2018-10-03 16:38:02 +02001449 /* Note: we don't send any error if some data were already sent */
Christopher Faulet9768c262018-10-22 09:34:31 +02001450 htx_reply_and_close(s, txn->status, NULL);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001451 } else {
1452 txn->status = 400;
Christopher Faulet9768c262018-10-22 09:34:31 +02001453 htx_reply_and_close(s, txn->status, http_error_message(s));
Christopher Faulete0768eb2018-10-03 16:38:02 +02001454 }
1455 req->analysers &= AN_REQ_FLT_END;
1456 s->res.analysers &= AN_RES_FLT_END; /* we're in data phase, we want to abort both directions */
1457
1458 if (!(s->flags & SF_ERR_MASK))
1459 s->flags |= SF_ERR_PRXCOND;
1460 if (!(s->flags & SF_FINST_MASK)) {
1461 if (txn->rsp.msg_state < HTTP_MSG_ERROR)
1462 s->flags |= SF_FINST_H;
1463 else
1464 s->flags |= SF_FINST_D;
1465 }
1466 return 0;
1467
1468 aborted_xfer:
1469 txn->req.err_state = txn->req.msg_state;
1470 txn->req.msg_state = HTTP_MSG_ERROR;
Christopher Faulet9768c262018-10-22 09:34:31 +02001471 if (txn->status > 0) {
Christopher Faulete0768eb2018-10-03 16:38:02 +02001472 /* Note: we don't send any error if some data were already sent */
Christopher Faulet9768c262018-10-22 09:34:31 +02001473 htx_reply_and_close(s, txn->status, NULL);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001474 } else {
1475 txn->status = 502;
Christopher Faulet9768c262018-10-22 09:34:31 +02001476 htx_reply_and_close(s, txn->status, http_error_message(s));
Christopher Faulete0768eb2018-10-03 16:38:02 +02001477 }
1478 req->analysers &= AN_REQ_FLT_END;
1479 s->res.analysers &= AN_RES_FLT_END; /* we're in data phase, we want to abort both directions */
1480
1481 HA_ATOMIC_ADD(&sess->fe->fe_counters.srv_aborts, 1);
1482 HA_ATOMIC_ADD(&s->be->be_counters.srv_aborts, 1);
1483 if (objt_server(s->target))
1484 HA_ATOMIC_ADD(&objt_server(s->target)->counters.srv_aborts, 1);
1485
1486 if (!(s->flags & SF_ERR_MASK))
1487 s->flags |= SF_ERR_SRVCL;
1488 if (!(s->flags & SF_FINST_MASK)) {
1489 if (txn->rsp.msg_state < HTTP_MSG_ERROR)
1490 s->flags |= SF_FINST_H;
1491 else
1492 s->flags |= SF_FINST_D;
1493 }
1494 return 0;
1495}
1496
1497/* This stream analyser waits for a complete HTTP response. It returns 1 if the
1498 * processing can continue on next analysers, or zero if it either needs more
1499 * data or wants to immediately abort the response (eg: timeout, error, ...). It
1500 * is tied to AN_RES_WAIT_HTTP and may may remove itself from s->res.analysers
1501 * when it has nothing left to do, and may remove any analyser when it wants to
1502 * abort.
1503 */
1504int htx_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
1505{
Christopher Faulet9768c262018-10-22 09:34:31 +02001506 /*
1507 * We will analyze a complete HTTP response to check the its syntax.
1508 *
1509 * Once the start line and all headers are received, we may perform a
1510 * capture of the error (if any), and we will set a few fields. We also
1511 * logging and finally headers capture.
1512 */
Christopher Faulete0768eb2018-10-03 16:38:02 +02001513 struct session *sess = s->sess;
1514 struct http_txn *txn = s->txn;
1515 struct http_msg *msg = &txn->rsp;
Christopher Faulet9768c262018-10-22 09:34:31 +02001516 struct htx *htx;
1517 union h1_sl sl;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001518 int n;
1519
1520 DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
1521 now_ms, __FUNCTION__,
1522 s,
1523 rep,
1524 rep->rex, rep->wex,
1525 rep->flags,
1526 ci_data(rep),
1527 rep->analysers);
1528
Christopher Faulet9768c262018-10-22 09:34:31 +02001529 htx = htx_from_buf(&rep->buf);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001530
1531 /*
1532 * Now we quickly check if we have found a full valid response.
1533 * If not so, we check the FD and buffer states before leaving.
1534 * A full response is indicated by the fact that we have seen
1535 * the double LF/CRLF, so the state is >= HTTP_MSG_BODY. Invalid
1536 * responses are checked first.
1537 *
1538 * Depending on whether the client is still there or not, we
1539 * may send an error response back or not. Note that normally
1540 * we should only check for HTTP status there, and check I/O
1541 * errors somewhere else.
1542 */
Christopher Faulet9768c262018-10-22 09:34:31 +02001543 if (unlikely(htx_is_empty(htx) || htx_get_tail_type(htx) < HTX_BLK_EOH)) {
1544 /* 1: have we encountered a read error ? */
1545 if (rep->flags & CF_READ_ERROR) {
1546 if (txn->flags & TX_NOT_FIRST)
Christopher Faulete0768eb2018-10-03 16:38:02 +02001547 goto abort_keep_alive;
1548
1549 HA_ATOMIC_ADD(&s->be->be_counters.failed_resp, 1);
1550 if (objt_server(s->target)) {
1551 HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_resp, 1);
1552 health_adjust(objt_server(s->target), HANA_STATUS_HTTP_READ_ERROR);
1553 }
1554
Christopher Faulete0768eb2018-10-03 16:38:02 +02001555 rep->analysers &= AN_RES_FLT_END;
1556 txn->status = 502;
1557
1558 /* Check to see if the server refused the early data.
1559 * If so, just send a 425
1560 */
1561 if (objt_cs(s->si[1].end)) {
1562 struct connection *conn = objt_cs(s->si[1].end)->conn;
1563
1564 if (conn->err_code == CO_ER_SSL_EARLY_FAILED)
1565 txn->status = 425;
1566 }
1567
1568 s->si[1].flags |= SI_FL_NOLINGER;
Christopher Faulet9768c262018-10-22 09:34:31 +02001569 htx_reply_and_close(s, txn->status, http_error_message(s));
Christopher Faulete0768eb2018-10-03 16:38:02 +02001570
1571 if (!(s->flags & SF_ERR_MASK))
1572 s->flags |= SF_ERR_SRVCL;
1573 if (!(s->flags & SF_FINST_MASK))
1574 s->flags |= SF_FINST_H;
1575 return 0;
1576 }
1577
Christopher Faulet9768c262018-10-22 09:34:31 +02001578 /* 2: read timeout : return a 504 to the client. */
Christopher Faulete0768eb2018-10-03 16:38:02 +02001579 else if (rep->flags & CF_READ_TIMEOUT) {
Christopher Faulete0768eb2018-10-03 16:38:02 +02001580 HA_ATOMIC_ADD(&s->be->be_counters.failed_resp, 1);
1581 if (objt_server(s->target)) {
1582 HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_resp, 1);
1583 health_adjust(objt_server(s->target), HANA_STATUS_HTTP_READ_TIMEOUT);
1584 }
1585
Christopher Faulete0768eb2018-10-03 16:38:02 +02001586 rep->analysers &= AN_RES_FLT_END;
1587 txn->status = 504;
1588 s->si[1].flags |= SI_FL_NOLINGER;
Christopher Faulet9768c262018-10-22 09:34:31 +02001589 htx_reply_and_close(s, txn->status, http_error_message(s));
Christopher Faulete0768eb2018-10-03 16:38:02 +02001590
1591 if (!(s->flags & SF_ERR_MASK))
1592 s->flags |= SF_ERR_SRVTO;
1593 if (!(s->flags & SF_FINST_MASK))
1594 s->flags |= SF_FINST_H;
1595 return 0;
1596 }
1597
Christopher Faulet9768c262018-10-22 09:34:31 +02001598 /* 3: client abort with an abortonclose */
Christopher Faulete0768eb2018-10-03 16:38:02 +02001599 else if ((rep->flags & CF_SHUTR) && ((s->req.flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))) {
1600 HA_ATOMIC_ADD(&sess->fe->fe_counters.cli_aborts, 1);
1601 HA_ATOMIC_ADD(&s->be->be_counters.cli_aborts, 1);
1602 if (objt_server(s->target))
1603 HA_ATOMIC_ADD(&objt_server(s->target)->counters.cli_aborts, 1);
1604
1605 rep->analysers &= AN_RES_FLT_END;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001606 txn->status = 400;
Christopher Faulet9768c262018-10-22 09:34:31 +02001607 htx_reply_and_close(s, txn->status, http_error_message(s));
Christopher Faulete0768eb2018-10-03 16:38:02 +02001608
1609 if (!(s->flags & SF_ERR_MASK))
1610 s->flags |= SF_ERR_CLICL;
1611 if (!(s->flags & SF_FINST_MASK))
1612 s->flags |= SF_FINST_H;
1613
1614 /* process_stream() will take care of the error */
1615 return 0;
1616 }
1617
Christopher Faulet9768c262018-10-22 09:34:31 +02001618 /* 4: close from server, capture the response if the server has started to respond */
Christopher Faulete0768eb2018-10-03 16:38:02 +02001619 else if (rep->flags & CF_SHUTR) {
Christopher Faulet9768c262018-10-22 09:34:31 +02001620 if (txn->flags & TX_NOT_FIRST)
Christopher Faulete0768eb2018-10-03 16:38:02 +02001621 goto abort_keep_alive;
1622
1623 HA_ATOMIC_ADD(&s->be->be_counters.failed_resp, 1);
1624 if (objt_server(s->target)) {
1625 HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_resp, 1);
1626 health_adjust(objt_server(s->target), HANA_STATUS_HTTP_BROKEN_PIPE);
1627 }
1628
Christopher Faulete0768eb2018-10-03 16:38:02 +02001629 rep->analysers &= AN_RES_FLT_END;
1630 txn->status = 502;
1631 s->si[1].flags |= SI_FL_NOLINGER;
Christopher Faulet9768c262018-10-22 09:34:31 +02001632 htx_reply_and_close(s, txn->status, http_error_message(s));
Christopher Faulete0768eb2018-10-03 16:38:02 +02001633
1634 if (!(s->flags & SF_ERR_MASK))
1635 s->flags |= SF_ERR_SRVCL;
1636 if (!(s->flags & SF_FINST_MASK))
1637 s->flags |= SF_FINST_H;
1638 return 0;
1639 }
1640
Christopher Faulet9768c262018-10-22 09:34:31 +02001641 /* 5: write error to client (we don't send any message then) */
Christopher Faulete0768eb2018-10-03 16:38:02 +02001642 else if (rep->flags & CF_WRITE_ERROR) {
Christopher Faulet9768c262018-10-22 09:34:31 +02001643 if (txn->flags & TX_NOT_FIRST)
Christopher Faulete0768eb2018-10-03 16:38:02 +02001644 goto abort_keep_alive;
1645
1646 HA_ATOMIC_ADD(&s->be->be_counters.failed_resp, 1);
1647 rep->analysers &= AN_RES_FLT_END;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001648
1649 if (!(s->flags & SF_ERR_MASK))
1650 s->flags |= SF_ERR_CLICL;
1651 if (!(s->flags & SF_FINST_MASK))
1652 s->flags |= SF_FINST_H;
1653
1654 /* process_stream() will take care of the error */
1655 return 0;
1656 }
1657
1658 channel_dont_close(rep);
1659 rep->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */
1660 return 0;
1661 }
1662
1663 /* More interesting part now : we know that we have a complete
1664 * response which at least looks like HTTP. We have an indicator
1665 * of each header's length, so we can parse them quickly.
1666 */
1667
Christopher Faulet9768c262018-10-22 09:34:31 +02001668 msg->msg_state = HTTP_MSG_BODY;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001669
Christopher Faulet9768c262018-10-22 09:34:31 +02001670 /* 0: we might have to print this header in debug mode */
1671 if (unlikely((global.mode & MODE_DEBUG) &&
1672 (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
1673 int32_t pos;
1674
1675 htx_debug_stline("srvrep", s, http_find_stline(htx));
1676
1677 for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
1678 struct htx_blk *blk = htx_get_blk(htx, pos);
1679 enum htx_blk_type type = htx_get_blk_type(blk);
1680
1681 if (type == HTX_BLK_EOH)
1682 break;
1683 if (type != HTX_BLK_HDR)
1684 continue;
1685
1686 htx_debug_hdr("srvhdr", s,
1687 htx_get_blk_name(htx, blk),
1688 htx_get_blk_value(htx, blk));
1689 }
1690 }
1691
1692 /* 1: get the status code */
1693 sl = http_find_stline(htx);
1694 txn->status = sl.st.status;
1695 if (htx->extra != ULLONG_MAX)
1696 msg->flags |= HTTP_MSGF_XFER_LEN;
1697
1698 /* ... and check if the request is HTTP/1.1 or above */
1699 if ((sl.st.v.len == 8) &&
1700 ((*(sl.st.v.ptr + 5) > '1') ||
1701 ((*(sl.st.v.ptr + 5) == '1') && (*(sl.st.v.ptr + 7) >= '1'))))
1702 msg->flags |= HTTP_MSGF_VER_11;
1703
1704 n = txn->status / 100;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001705 if (n < 1 || n > 5)
1706 n = 0;
Christopher Faulet9768c262018-10-22 09:34:31 +02001707
Christopher Faulete0768eb2018-10-03 16:38:02 +02001708 /* when the client triggers a 4xx from the server, it's most often due
1709 * to a missing object or permission. These events should be tracked
1710 * because if they happen often, it may indicate a brute force or a
1711 * vulnerability scan.
1712 */
1713 if (n == 4)
1714 stream_inc_http_err_ctr(s);
1715
1716 if (objt_server(s->target))
1717 HA_ATOMIC_ADD(&objt_server(s->target)->counters.p.http.rsp[n], 1);
1718
Christopher Faulete0768eb2018-10-03 16:38:02 +02001719 /* Adjust server's health based on status code. Note: status codes 501
1720 * and 505 are triggered on demand by client request, so we must not
1721 * count them as server failures.
1722 */
1723 if (objt_server(s->target)) {
1724 if (txn->status >= 100 && (txn->status < 500 || txn->status == 501 || txn->status == 505))
1725 health_adjust(objt_server(s->target), HANA_STATUS_HTTP_OK);
1726 else
1727 health_adjust(objt_server(s->target), HANA_STATUS_HTTP_STS);
1728 }
1729
1730 /*
1731 * We may be facing a 100-continue response, or any other informational
1732 * 1xx response which is non-final, in which case this is not the right
1733 * response, and we're waiting for the next one. Let's allow this response
1734 * to go to the client and wait for the next one. There's an exception for
1735 * 101 which is used later in the code to switch protocols.
1736 */
1737 if (txn->status < 200 &&
1738 (txn->status == 100 || txn->status >= 102)) {
Christopher Faulet9768c262018-10-22 09:34:31 +02001739 //FLT_STRM_CB(s, flt_htx_reset(s, http, htx));
1740 c_adv(rep, htx->data);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001741 msg->msg_state = HTTP_MSG_RPBEFORE;
1742 txn->status = 0;
1743 s->logs.t_data = -1; /* was not a response yet */
Christopher Faulet9768c262018-10-22 09:34:31 +02001744 return 0;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001745 }
1746
1747 /*
1748 * 2: check for cacheability.
1749 */
1750
1751 switch (txn->status) {
1752 case 200:
1753 case 203:
1754 case 204:
1755 case 206:
1756 case 300:
1757 case 301:
1758 case 404:
1759 case 405:
1760 case 410:
1761 case 414:
1762 case 501:
1763 break;
1764 default:
1765 /* RFC7231#6.1:
1766 * Responses with status codes that are defined as
1767 * cacheable by default (e.g., 200, 203, 204, 206,
1768 * 300, 301, 404, 405, 410, 414, and 501 in this
1769 * specification) can be reused by a cache with
1770 * heuristic expiration unless otherwise indicated
1771 * by the method definition or explicit cache
1772 * controls [RFC7234]; all other status codes are
1773 * not cacheable by default.
1774 */
1775 txn->flags &= ~(TX_CACHEABLE | TX_CACHE_COOK);
1776 break;
1777 }
1778
1779 /*
1780 * 3: we may need to capture headers
1781 */
1782 s->logs.logwait &= ~LW_RESP;
1783 if (unlikely((s->logs.logwait & LW_RSPHDR) && s->res_cap))
Christopher Faulet9768c262018-10-22 09:34:31 +02001784 htx_capture_headers(htx, s->res_cap, sess->fe->rsp_cap);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001785
Christopher Faulet9768c262018-10-22 09:34:31 +02001786 /* Skip parsing if no content length is possible. */
Christopher Faulete0768eb2018-10-03 16:38:02 +02001787 if (unlikely((txn->meth == HTTP_METH_CONNECT && txn->status == 200) ||
1788 txn->status == 101)) {
1789 /* Either we've established an explicit tunnel, or we're
1790 * switching the protocol. In both cases, we're very unlikely
1791 * to understand the next protocols. We have to switch to tunnel
1792 * mode, so that we transfer the request and responses then let
1793 * this protocol pass unmodified. When we later implement specific
1794 * parsers for such protocols, we'll want to check the Upgrade
1795 * header which contains information about that protocol for
1796 * responses with status 101 (eg: see RFC2817 about TLS).
1797 */
1798 txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_TUN;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001799 }
1800
Christopher Faulete0768eb2018-10-03 16:38:02 +02001801 /* we want to have the response time before we start processing it */
1802 s->logs.t_data = tv_ms_elapsed(&s->logs.tv_accept, &now);
1803
1804 /* end of job, return OK */
1805 rep->analysers &= ~an_bit;
1806 rep->analyse_exp = TICK_ETERNITY;
1807 channel_auto_close(rep);
1808 return 1;
1809
1810 abort_keep_alive:
1811 /* A keep-alive request to the server failed on a network error.
1812 * The client is required to retry. We need to close without returning
1813 * any other information so that the client retries.
1814 */
1815 txn->status = 0;
1816 rep->analysers &= AN_RES_FLT_END;
1817 s->req.analysers &= AN_REQ_FLT_END;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001818 s->logs.logwait = 0;
1819 s->logs.level = 0;
1820 s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
Christopher Faulet9768c262018-10-22 09:34:31 +02001821 htx_reply_and_close(s, txn->status, NULL);
Christopher Faulete0768eb2018-10-03 16:38:02 +02001822 return 0;
1823}
1824
1825/* This function performs all the processing enabled for the current response.
1826 * It normally returns 1 unless it wants to break. It relies on buffers flags,
1827 * and updates s->res.analysers. It might make sense to explode it into several
1828 * other functions. It works like process_request (see indications above).
1829 */
1830int htx_process_res_common(struct stream *s, struct channel *rep, int an_bit, struct proxy *px)
1831{
1832 struct session *sess = s->sess;
1833 struct http_txn *txn = s->txn;
1834 struct http_msg *msg = &txn->rsp;
1835 struct proxy *cur_proxy;
1836 struct cond_wordlist *wl;
1837 enum rule_result ret = HTTP_RULE_RES_CONT;
1838
Christopher Faulet9768c262018-10-22 09:34:31 +02001839 // TODO: Disabled for now
1840 rep->analysers &= ~AN_RES_FLT_XFER_DATA;
1841 rep->analysers |= AN_RES_HTTP_XFER_BODY;
1842 rep->analyse_exp = TICK_ETERNITY;
1843 rep->analysers &= ~an_bit;
1844 return 1;
1845
Christopher Faulete0768eb2018-10-03 16:38:02 +02001846 DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
1847 now_ms, __FUNCTION__,
1848 s,
1849 rep,
1850 rep->rex, rep->wex,
1851 rep->flags,
1852 ci_data(rep),
1853 rep->analysers);
1854
1855 if (unlikely(msg->msg_state < HTTP_MSG_BODY)) /* we need more data */
1856 return 0;
1857
1858 /* The stats applet needs to adjust the Connection header but we don't
1859 * apply any filter there.
1860 */
1861 if (unlikely(objt_applet(s->target) == &http_stats_applet)) {
1862 rep->analysers &= ~an_bit;
1863 rep->analyse_exp = TICK_ETERNITY;
Christopher Fauletf2824e62018-10-01 12:12:37 +02001864 goto end;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001865 }
1866
1867 /*
1868 * We will have to evaluate the filters.
1869 * As opposed to version 1.2, now they will be evaluated in the
1870 * filters order and not in the header order. This means that
1871 * each filter has to be validated among all headers.
1872 *
1873 * Filters are tried with ->be first, then with ->fe if it is
1874 * different from ->be.
1875 *
1876 * Maybe we are in resume condiion. In this case I choose the
1877 * "struct proxy" which contains the rule list matching the resume
1878 * pointer. If none of theses "struct proxy" match, I initialise
1879 * the process with the first one.
1880 *
1881 * In fact, I check only correspondance betwwen the current list
1882 * pointer and the ->fe rule list. If it doesn't match, I initialize
1883 * the loop with the ->be.
1884 */
1885 if (s->current_rule_list == &sess->fe->http_res_rules)
1886 cur_proxy = sess->fe;
1887 else
1888 cur_proxy = s->be;
1889 while (1) {
1890 struct proxy *rule_set = cur_proxy;
1891
1892 /* evaluate http-response rules */
1893 if (ret == HTTP_RULE_RES_CONT) {
1894 ret = http_res_get_intercept_rule(cur_proxy, &cur_proxy->http_res_rules, s);
1895
1896 if (ret == HTTP_RULE_RES_BADREQ)
1897 goto return_srv_prx_502;
1898
1899 if (ret == HTTP_RULE_RES_DONE) {
1900 rep->analysers &= ~an_bit;
1901 rep->analyse_exp = TICK_ETERNITY;
1902 return 1;
1903 }
1904 }
1905
1906 /* we need to be called again. */
1907 if (ret == HTTP_RULE_RES_YIELD) {
1908 channel_dont_close(rep);
1909 return 0;
1910 }
1911
1912 /* try headers filters */
1913 if (rule_set->rsp_exp != NULL) {
1914 if (apply_filters_to_response(s, rep, rule_set) < 0) {
1915 return_bad_resp:
1916 if (objt_server(s->target)) {
1917 HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_resp, 1);
1918 health_adjust(objt_server(s->target), HANA_STATUS_HTTP_RSP);
1919 }
1920 HA_ATOMIC_ADD(&s->be->be_counters.failed_resp, 1);
1921 return_srv_prx_502:
1922 rep->analysers &= AN_RES_FLT_END;
1923 txn->status = 502;
1924 s->logs.t_data = -1; /* was not a valid response */
1925 s->si[1].flags |= SI_FL_NOLINGER;
1926 channel_truncate(rep);
1927 http_reply_and_close(s, txn->status, http_error_message(s));
1928 if (!(s->flags & SF_ERR_MASK))
1929 s->flags |= SF_ERR_PRXCOND;
1930 if (!(s->flags & SF_FINST_MASK))
1931 s->flags |= SF_FINST_H;
1932 return 0;
1933 }
1934 }
1935
1936 /* has the response been denied ? */
1937 if (txn->flags & TX_SVDENY) {
1938 if (objt_server(s->target))
1939 HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_secu, 1);
1940
1941 HA_ATOMIC_ADD(&s->be->be_counters.denied_resp, 1);
1942 HA_ATOMIC_ADD(&sess->fe->fe_counters.denied_resp, 1);
1943 if (sess->listener->counters)
1944 HA_ATOMIC_ADD(&sess->listener->counters->denied_resp, 1);
1945
1946 goto return_srv_prx_502;
1947 }
1948
1949 /* add response headers from the rule sets in the same order */
1950 list_for_each_entry(wl, &rule_set->rsp_add, list) {
1951 if (txn->status < 200 && txn->status != 101)
1952 break;
1953 if (wl->cond) {
1954 int ret = acl_exec_cond(wl->cond, px, sess, s, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
1955 ret = acl_pass(ret);
1956 if (((struct acl_cond *)wl->cond)->pol == ACL_COND_UNLESS)
1957 ret = !ret;
1958 if (!ret)
1959 continue;
1960 }
1961 if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, wl->s, strlen(wl->s)) < 0))
1962 goto return_bad_resp;
1963 }
1964
1965 /* check whether we're already working on the frontend */
1966 if (cur_proxy == sess->fe)
1967 break;
1968 cur_proxy = sess->fe;
1969 }
1970
1971 /* After this point, this anayzer can't return yield, so we can
1972 * remove the bit corresponding to this analyzer from the list.
1973 *
1974 * Note that the intermediate returns and goto found previously
1975 * reset the analyzers.
1976 */
1977 rep->analysers &= ~an_bit;
1978 rep->analyse_exp = TICK_ETERNITY;
1979
1980 /* OK that's all we can do for 1xx responses */
1981 if (unlikely(txn->status < 200 && txn->status != 101))
Christopher Fauletf2824e62018-10-01 12:12:37 +02001982 goto end;
Christopher Faulete0768eb2018-10-03 16:38:02 +02001983
1984 /*
1985 * Now check for a server cookie.
1986 */
1987 if (s->be->cookie_name || sess->fe->capture_name || (s->be->options & PR_O_CHK_CACHE))
1988 manage_server_side_cookies(s, rep);
1989
1990 /*
1991 * Check for cache-control or pragma headers if required.
1992 */
1993 if ((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC))
1994 check_response_for_cacheability(s, rep);
1995
1996 /*
1997 * Add server cookie in the response if needed
1998 */
1999 if (objt_server(s->target) && (s->be->ck_opts & PR_CK_INS) &&
2000 !((txn->flags & TX_SCK_FOUND) && (s->be->ck_opts & PR_CK_PSV)) &&
2001 (!(s->flags & SF_DIRECT) ||
2002 ((s->be->cookie_maxidle || txn->cookie_last_date) &&
2003 (!txn->cookie_last_date || (txn->cookie_last_date - date.tv_sec) < 0)) ||
2004 (s->be->cookie_maxlife && !txn->cookie_first_date) || // set the first_date
2005 (!s->be->cookie_maxlife && txn->cookie_first_date)) && // remove the first_date
2006 (!(s->be->ck_opts & PR_CK_POST) || (txn->meth == HTTP_METH_POST)) &&
2007 !(s->flags & SF_IGNORE_PRST)) {
2008 /* the server is known, it's not the one the client requested, or the
2009 * cookie's last seen date needs to be refreshed. We have to
2010 * insert a set-cookie here, except if we want to insert only on POST
2011 * requests and this one isn't. Note that servers which don't have cookies
2012 * (eg: some backup servers) will return a full cookie removal request.
2013 */
2014 if (!objt_server(s->target)->cookie) {
2015 chunk_printf(&trash,
2016 "Set-Cookie: %s=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/",
2017 s->be->cookie_name);
2018 }
2019 else {
2020 chunk_printf(&trash, "Set-Cookie: %s=%s", s->be->cookie_name, objt_server(s->target)->cookie);
2021
2022 if (s->be->cookie_maxidle || s->be->cookie_maxlife) {
2023 /* emit last_date, which is mandatory */
2024 trash.area[trash.data++] = COOKIE_DELIM_DATE;
2025 s30tob64((date.tv_sec+3) >> 2,
2026 trash.area + trash.data);
2027 trash.data += 5;
2028
2029 if (s->be->cookie_maxlife) {
2030 /* emit first_date, which is either the original one or
2031 * the current date.
2032 */
2033 trash.area[trash.data++] = COOKIE_DELIM_DATE;
2034 s30tob64(txn->cookie_first_date ?
2035 txn->cookie_first_date >> 2 :
2036 (date.tv_sec+3) >> 2,
2037 trash.area + trash.data);
2038 trash.data += 5;
2039 }
2040 }
2041 chunk_appendf(&trash, "; path=/");
2042 }
2043
2044 if (s->be->cookie_domain)
2045 chunk_appendf(&trash, "; domain=%s", s->be->cookie_domain);
2046
2047 if (s->be->ck_opts & PR_CK_HTTPONLY)
2048 chunk_appendf(&trash, "; HttpOnly");
2049
2050 if (s->be->ck_opts & PR_CK_SECURE)
2051 chunk_appendf(&trash, "; Secure");
2052
2053 if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash.area, trash.data) < 0))
2054 goto return_bad_resp;
2055
2056 txn->flags &= ~TX_SCK_MASK;
2057 if (__objt_server(s->target)->cookie && (s->flags & SF_DIRECT))
2058 /* the server did not change, only the date was updated */
2059 txn->flags |= TX_SCK_UPDATED;
2060 else
2061 txn->flags |= TX_SCK_INSERTED;
2062
2063 /* Here, we will tell an eventual cache on the client side that we don't
2064 * want it to cache this reply because HTTP/1.0 caches also cache cookies !
2065 * Some caches understand the correct form: 'no-cache="set-cookie"', but
2066 * others don't (eg: apache <= 1.3.26). So we use 'private' instead.
2067 */
2068 if ((s->be->ck_opts & PR_CK_NOC) && (txn->flags & TX_CACHEABLE)) {
2069
2070 txn->flags &= ~TX_CACHEABLE & ~TX_CACHE_COOK;
2071
2072 if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx,
2073 "Cache-control: private", 22) < 0))
2074 goto return_bad_resp;
2075 }
2076 }
2077
2078 /*
2079 * Check if result will be cacheable with a cookie.
2080 * We'll block the response if security checks have caught
2081 * nasty things such as a cacheable cookie.
2082 */
2083 if (((txn->flags & (TX_CACHEABLE | TX_CACHE_COOK | TX_SCK_PRESENT)) ==
2084 (TX_CACHEABLE | TX_CACHE_COOK | TX_SCK_PRESENT)) &&
2085 (s->be->options & PR_O_CHK_CACHE)) {
2086 /* we're in presence of a cacheable response containing
2087 * a set-cookie header. We'll block it as requested by
2088 * the 'checkcache' option, and send an alert.
2089 */
2090 if (objt_server(s->target))
2091 HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_secu, 1);
2092
2093 HA_ATOMIC_ADD(&s->be->be_counters.denied_resp, 1);
2094 HA_ATOMIC_ADD(&sess->fe->fe_counters.denied_resp, 1);
2095 if (sess->listener->counters)
2096 HA_ATOMIC_ADD(&sess->listener->counters->denied_resp, 1);
2097
2098 ha_alert("Blocking cacheable cookie in response from instance %s, server %s.\n",
2099 s->be->id, objt_server(s->target) ? objt_server(s->target)->id : "<dispatch>");
2100 send_log(s->be, LOG_ALERT,
2101 "Blocking cacheable cookie in response from instance %s, server %s.\n",
2102 s->be->id, objt_server(s->target) ? objt_server(s->target)->id : "<dispatch>");
2103 goto return_srv_prx_502;
2104 }
2105
Christopher Fauletf2824e62018-10-01 12:12:37 +02002106 end:
Christopher Faulete0768eb2018-10-03 16:38:02 +02002107 /* Always enter in the body analyzer */
2108 rep->analysers &= ~AN_RES_FLT_XFER_DATA;
2109 rep->analysers |= AN_RES_HTTP_XFER_BODY;
2110
2111 /* if the user wants to log as soon as possible, without counting
2112 * bytes from the server, then this is the right moment. We have
2113 * to temporarily assign bytes_out to log what we currently have.
2114 */
2115 if (!LIST_ISEMPTY(&sess->fe->logformat) && !(s->logs.logwait & LW_BYTES)) {
2116 s->logs.t_close = s->logs.t_data; /* to get a valid end date */
2117 s->logs.bytes_out = txn->rsp.eoh;
2118 s->do_log(s);
2119 s->logs.bytes_out = 0;
2120 }
2121 return 1;
2122}
2123
2124/* This function is an analyser which forwards response body (including chunk
2125 * sizes if any). It is called as soon as we must forward, even if we forward
2126 * zero byte. The only situation where it must not be called is when we're in
2127 * tunnel mode and we want to forward till the close. It's used both to forward
2128 * remaining data and to resync after end of body. It expects the msg_state to
2129 * be between MSG_BODY and MSG_DONE (inclusive). It returns zero if it needs to
2130 * read more data, or 1 once we can go on with next request or end the stream.
2131 *
2132 * It is capable of compressing response data both in content-length mode and
2133 * in chunked mode. The state machines follows different flows depending on
2134 * whether content-length and chunked modes are used, since there are no
2135 * trailers in content-length :
2136 *
2137 * chk-mode cl-mode
2138 * ,----- BODY -----.
2139 * / \
2140 * V size > 0 V chk-mode
2141 * .--> SIZE -------------> DATA -------------> CRLF
2142 * | | size == 0 | last byte |
2143 * | v final crlf v inspected |
2144 * | TRAILERS -----------> DONE |
2145 * | |
2146 * `----------------------------------------------'
2147 *
2148 * Compression only happens in the DATA state, and must be flushed in final
2149 * states (TRAILERS/DONE) or when leaving on missing data. Normal forwarding
2150 * is performed at once on final states for all bytes parsed, or when leaving
2151 * on missing data.
2152 */
2153int htx_response_forward_body(struct stream *s, struct channel *res, int an_bit)
2154{
2155 struct session *sess = s->sess;
2156 struct http_txn *txn = s->txn;
2157 struct http_msg *msg = &s->txn->rsp;
Christopher Faulet9768c262018-10-22 09:34:31 +02002158 struct htx *htx;
2159 //int ret;
Christopher Faulete0768eb2018-10-03 16:38:02 +02002160
2161 DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
2162 now_ms, __FUNCTION__,
2163 s,
2164 res,
2165 res->rex, res->wex,
2166 res->flags,
2167 ci_data(res),
2168 res->analysers);
2169
Christopher Faulet9768c262018-10-22 09:34:31 +02002170 htx = htx_from_buf(&res->buf);
Christopher Faulete0768eb2018-10-03 16:38:02 +02002171
2172 if ((res->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) ||
Christopher Fauletf2824e62018-10-01 12:12:37 +02002173 ((res->flags & CF_SHUTW) && (res->to_forward || co_data(res)))) {
Christopher Faulete0768eb2018-10-03 16:38:02 +02002174 /* Output closed while we were sending data. We must abort and
2175 * wake the other side up.
2176 */
2177 msg->err_state = msg->msg_state;
2178 msg->msg_state = HTTP_MSG_ERROR;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002179 htx_end_response(s);
2180 htx_end_request(s);
Christopher Faulete0768eb2018-10-03 16:38:02 +02002181 return 1;
2182 }
2183
Christopher Faulet9768c262018-10-22 09:34:31 +02002184 if (msg->msg_state == HTTP_MSG_BODY)
2185 msg->msg_state = HTTP_MSG_DATA;
2186
Christopher Faulete0768eb2018-10-03 16:38:02 +02002187 /* in most states, we should abort in case of early close */
2188 channel_auto_close(res);
2189
Christopher Faulete0768eb2018-10-03 16:38:02 +02002190 if (res->to_forward) {
2191 /* We can't process the buffer's contents yet */
2192 res->flags |= CF_WAKE_WRITE;
2193 goto missing_data_or_waiting;
2194 }
2195
Christopher Faulet9768c262018-10-22 09:34:31 +02002196 if (msg->msg_state >= HTTP_MSG_DONE)
2197 goto done;
2198
2199 /* Forward all input data. We get it by removing all outgoing data not
2200 * forwarded yet from HTX data size.
2201 */
2202 c_adv(res, htx->data - co_data(res));
2203
2204 /* To let the function channel_forward work as expected we must update
2205 * the channel's buffer to pretend there is no more input data. The
2206 * right length is then restored. We must do that, because when an HTX
2207 * message is stored into a buffer, it appears as full.
2208 */
2209 b_set_data(&res->buf, co_data(res));
2210 if (htx->extra != ULLONG_MAX)
2211 htx->extra -= channel_forward(res, htx->extra);
2212 b_set_data(&res->buf, b_size(&res->buf));
2213
2214 if (!(msg->flags & HTTP_MSGF_XFER_LEN)) {
2215 /* The server still sending data that should be filtered */
2216 if (res->flags & CF_SHUTR || !HAS_DATA_FILTERS(s, res)) {
2217 msg->msg_state = HTTP_MSG_TUNNEL;
2218 goto done;
2219 }
Christopher Faulete0768eb2018-10-03 16:38:02 +02002220 }
2221
Christopher Faulet9768c262018-10-22 09:34:31 +02002222 /* Check if the end-of-message is reached and if so, switch the message
2223 * in HTTP_MSG_DONE state.
2224 */
2225 if (htx_get_tail_type(htx) != HTX_BLK_EOM)
2226 goto missing_data_or_waiting;
2227
2228 msg->msg_state = HTTP_MSG_DONE;
2229
2230 done:
Christopher Faulete0768eb2018-10-03 16:38:02 +02002231 /* other states, DONE...TUNNEL */
Christopher Faulet9768c262018-10-22 09:34:31 +02002232 channel_dont_close(res);
2233
Christopher Fauletf2824e62018-10-01 12:12:37 +02002234 htx_end_response(s);
Christopher Faulete0768eb2018-10-03 16:38:02 +02002235 if (!(res->analysers & an_bit)) {
Christopher Fauletf2824e62018-10-01 12:12:37 +02002236 htx_end_request(s);
Christopher Faulete0768eb2018-10-03 16:38:02 +02002237 if (unlikely(msg->msg_state == HTTP_MSG_ERROR)) {
2238 if (res->flags & CF_SHUTW) {
2239 /* response errors are most likely due to the
2240 * client aborting the transfer. */
2241 goto aborted_xfer;
2242 }
Christopher Faulete0768eb2018-10-03 16:38:02 +02002243 goto return_bad_res;
2244 }
2245 return 1;
2246 }
2247 return 0;
2248
2249 missing_data_or_waiting:
2250 if (res->flags & CF_SHUTW)
2251 goto aborted_xfer;
2252
2253 /* stop waiting for data if the input is closed before the end. If the
2254 * client side was already closed, it means that the client has aborted,
2255 * so we don't want to count this as a server abort. Otherwise it's a
2256 * server abort.
2257 */
Christopher Faulet9768c262018-10-22 09:34:31 +02002258 if (msg->msg_state < HTTP_MSG_DONE && res->flags & CF_SHUTR) {
Christopher Faulete0768eb2018-10-03 16:38:02 +02002259 if ((s->req.flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))
2260 goto aborted_xfer;
2261 /* If we have some pending data, we continue the processing */
Christopher Faulet9768c262018-10-22 09:34:31 +02002262 if (htx_is_empty(htx)) {
Christopher Faulete0768eb2018-10-03 16:38:02 +02002263 if (!(s->flags & SF_ERR_MASK))
2264 s->flags |= SF_ERR_SRVCL;
2265 HA_ATOMIC_ADD(&s->be->be_counters.srv_aborts, 1);
2266 if (objt_server(s->target))
2267 HA_ATOMIC_ADD(&objt_server(s->target)->counters.srv_aborts, 1);
2268 goto return_bad_res_stats_ok;
2269 }
2270 }
2271
Christopher Faulete0768eb2018-10-03 16:38:02 +02002272 /* When TE: chunked is used, we need to get there again to parse
2273 * remaining chunks even if the server has closed, so we don't want to
Christopher Faulet9768c262018-10-22 09:34:31 +02002274 * set CF_DONTCLOSE. Similarly when there is a content-leng or if there
2275 * are filters registered on the stream, we don't want to forward a
2276 * close
Christopher Faulete0768eb2018-10-03 16:38:02 +02002277 */
Christopher Faulet9768c262018-10-22 09:34:31 +02002278 if ((msg->flags & HTTP_MSGF_XFER_LEN) || HAS_DATA_FILTERS(s, res))
Christopher Faulete0768eb2018-10-03 16:38:02 +02002279 channel_dont_close(res);
2280
Christopher Faulet9768c262018-10-22 09:34:31 +02002281#if 0 // FIXME [Cf]: Probably not required now, but I need more time to think
2282 // about if
2283
Christopher Faulete0768eb2018-10-03 16:38:02 +02002284 /* We know that more data are expected, but we couldn't send more that
2285 * what we did. So we always set the CF_EXPECT_MORE flag so that the
2286 * system knows it must not set a PUSH on this first part. Interactive
2287 * modes are already handled by the stream sock layer. We must not do
2288 * this in content-length mode because it could present the MSG_MORE
2289 * flag with the last block of forwarded data, which would cause an
2290 * additional delay to be observed by the receiver.
2291 */
2292 if ((msg->flags & HTTP_MSGF_TE_CHNK) || (msg->flags & HTTP_MSGF_COMPRESSING))
2293 res->flags |= CF_EXPECT_MORE;
Christopher Faulet9768c262018-10-22 09:34:31 +02002294#endif
Christopher Faulete0768eb2018-10-03 16:38:02 +02002295
2296 /* the stream handler will take care of timeouts and errors */
2297 return 0;
2298
2299 return_bad_res: /* let's centralize all bad responses */
2300 HA_ATOMIC_ADD(&s->be->be_counters.failed_resp, 1);
2301 if (objt_server(s->target))
2302 HA_ATOMIC_ADD(&objt_server(s->target)->counters.failed_resp, 1);
2303
2304 return_bad_res_stats_ok:
2305 txn->rsp.err_state = txn->rsp.msg_state;
2306 txn->rsp.msg_state = HTTP_MSG_ERROR;
2307 /* don't send any error message as we're in the body */
Christopher Faulet9768c262018-10-22 09:34:31 +02002308 htx_reply_and_close(s, txn->status, NULL);
Christopher Faulete0768eb2018-10-03 16:38:02 +02002309 res->analysers &= AN_RES_FLT_END;
2310 s->req.analysers &= AN_REQ_FLT_END; /* we're in data phase, we want to abort both directions */
2311 if (objt_server(s->target))
2312 health_adjust(objt_server(s->target), HANA_STATUS_HTTP_HDRRSP);
2313
2314 if (!(s->flags & SF_ERR_MASK))
2315 s->flags |= SF_ERR_PRXCOND;
2316 if (!(s->flags & SF_FINST_MASK))
2317 s->flags |= SF_FINST_D;
2318 return 0;
2319
2320 aborted_xfer:
2321 txn->rsp.err_state = txn->rsp.msg_state;
2322 txn->rsp.msg_state = HTTP_MSG_ERROR;
2323 /* don't send any error message as we're in the body */
Christopher Faulet9768c262018-10-22 09:34:31 +02002324 htx_reply_and_close(s, txn->status, NULL);
Christopher Faulete0768eb2018-10-03 16:38:02 +02002325 res->analysers &= AN_RES_FLT_END;
2326 s->req.analysers &= AN_REQ_FLT_END; /* we're in data phase, we want to abort both directions */
2327
2328 HA_ATOMIC_ADD(&sess->fe->fe_counters.cli_aborts, 1);
2329 HA_ATOMIC_ADD(&s->be->be_counters.cli_aborts, 1);
2330 if (objt_server(s->target))
2331 HA_ATOMIC_ADD(&objt_server(s->target)->counters.cli_aborts, 1);
2332
2333 if (!(s->flags & SF_ERR_MASK))
2334 s->flags |= SF_ERR_CLICL;
2335 if (!(s->flags & SF_FINST_MASK))
2336 s->flags |= SF_FINST_D;
2337 return 0;
2338}
2339
Christopher Faulet0f226952018-10-22 09:29:56 +02002340void htx_adjust_conn_mode(struct stream *s, struct http_txn *txn)
Christopher Fauletf2824e62018-10-01 12:12:37 +02002341{
2342 struct proxy *fe = strm_fe(s);
2343 int tmp = TX_CON_WANT_CLO;
2344
2345 if ((fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
2346 tmp = TX_CON_WANT_TUN;
2347
2348 if ((txn->flags & TX_CON_WANT_MSK) < tmp)
Christopher Faulet0f226952018-10-22 09:29:56 +02002349 txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | tmp;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002350}
2351
2352/* Perform an HTTP redirect based on the information in <rule>. The function
2353 * returns non-zero on success, or zero in case of a, irrecoverable error such
2354 * as too large a request to build a valid response.
2355 */
2356int htx_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struct http_txn *txn)
2357{
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002358 struct htx *htx = htx_from_buf(&s->req.buf);
2359 union h1_sl sl;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002360 const char *msg_fmt;
2361 struct buffer *chunk;
2362 int ret = 0;
2363
2364 chunk = alloc_trash_chunk();
2365 if (!chunk)
2366 goto leave;
2367
2368 /* build redirect message */
2369 switch(rule->code) {
2370 case 308:
2371 msg_fmt = HTTP_308;
2372 break;
2373 case 307:
2374 msg_fmt = HTTP_307;
2375 break;
2376 case 303:
2377 msg_fmt = HTTP_303;
2378 break;
2379 case 301:
2380 msg_fmt = HTTP_301;
2381 break;
2382 case 302:
2383 default:
2384 msg_fmt = HTTP_302;
2385 break;
2386 }
2387
2388 if (unlikely(!chunk_strcpy(chunk, msg_fmt)))
2389 goto leave;
2390
2391 switch(rule->type) {
2392 case REDIRECT_TYPE_SCHEME: {
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002393 struct http_hdr_ctx ctx;
2394 struct ist path, host;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002395
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002396 host = ist("");
2397 ctx.blk = NULL;
2398 if (http_find_header(htx, ist("Host"), &ctx, 0))
2399 host = ctx.value;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002400
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002401 sl = http_find_stline(htx);
2402 path = http_get_path(sl.rq.u);
Christopher Fauletf2824e62018-10-01 12:12:37 +02002403 /* build message using path */
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002404 if (path.ptr) {
Christopher Fauletf2824e62018-10-01 12:12:37 +02002405 if (rule->flags & REDIRECT_FLAG_DROP_QS) {
2406 int qs = 0;
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002407 while (qs < path.len) {
2408 if (*(path.ptr + qs) == '?') {
2409 path.len = qs;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002410 break;
2411 }
2412 qs++;
2413 }
2414 }
Christopher Fauletf2824e62018-10-01 12:12:37 +02002415 }
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002416 else
2417 path = ist("/");
Christopher Fauletf2824e62018-10-01 12:12:37 +02002418
2419 if (rule->rdr_str) { /* this is an old "redirect" rule */
Christopher Fauletf2824e62018-10-01 12:12:37 +02002420 /* add scheme */
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002421 if (!chunk_memcat(chunk, rule->rdr_str, rule->rdr_len))
2422 goto leave;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002423 }
2424 else {
2425 /* add scheme with executing log format */
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002426 chunk->data += build_logline(s, chunk->area + chunk->data,
2427 chunk->size - chunk->data,
2428 &rule->rdr_fmt);
Christopher Fauletf2824e62018-10-01 12:12:37 +02002429 }
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002430 /* add "://" + host + path */
2431 if (!chunk_memcat(chunk, "://", 3) ||
2432 !chunk_memcat(chunk, host.ptr, host.len) ||
2433 !chunk_memcat(chunk, path.ptr, path.len))
2434 goto leave;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002435
2436 /* append a slash at the end of the location if needed and missing */
2437 if (chunk->data && chunk->area[chunk->data - 1] != '/' &&
2438 (rule->flags & REDIRECT_FLAG_APPEND_SLASH)) {
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002439 if (chunk->data + 1 >= chunk->size)
Christopher Fauletf2824e62018-10-01 12:12:37 +02002440 goto leave;
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002441 chunk->area[chunk->data++] = '/';
Christopher Fauletf2824e62018-10-01 12:12:37 +02002442 }
Christopher Fauletf2824e62018-10-01 12:12:37 +02002443 break;
2444 }
2445 case REDIRECT_TYPE_PREFIX: {
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002446 struct ist path;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002447
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002448 sl = http_find_stline(htx);
2449 path = http_get_path(sl.rq.u);
Christopher Fauletf2824e62018-10-01 12:12:37 +02002450 /* build message using path */
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002451 if (path.ptr) {
Christopher Fauletf2824e62018-10-01 12:12:37 +02002452 if (rule->flags & REDIRECT_FLAG_DROP_QS) {
2453 int qs = 0;
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002454 while (qs < path.len) {
2455 if (*(path.ptr + qs) == '?') {
2456 path.len = qs;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002457 break;
2458 }
2459 qs++;
2460 }
2461 }
Christopher Fauletf2824e62018-10-01 12:12:37 +02002462 }
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002463 else
2464 path = ist("/");
Christopher Fauletf2824e62018-10-01 12:12:37 +02002465
2466 if (rule->rdr_str) { /* this is an old "redirect" rule */
Christopher Fauletf2824e62018-10-01 12:12:37 +02002467 /* add prefix. Note that if prefix == "/", we don't want to
2468 * add anything, otherwise it makes it hard for the user to
2469 * configure a self-redirection.
2470 */
2471 if (rule->rdr_len != 1 || *rule->rdr_str != '/') {
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002472 if (!chunk_memcat(chunk, rule->rdr_str, rule->rdr_len))
2473 goto leave;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002474 }
2475 }
2476 else {
2477 /* add prefix with executing log format */
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002478 chunk->data += build_logline(s, chunk->area + chunk->data,
2479 chunk->size - chunk->data,
2480 &rule->rdr_fmt);
Christopher Fauletf2824e62018-10-01 12:12:37 +02002481 }
2482
2483 /* add path */
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002484 if (!chunk_memcat(chunk, path.ptr, path.len))
2485 goto leave;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002486
2487 /* append a slash at the end of the location if needed and missing */
2488 if (chunk->data && chunk->area[chunk->data - 1] != '/' &&
2489 (rule->flags & REDIRECT_FLAG_APPEND_SLASH)) {
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002490 if (chunk->data + 1 >= chunk->size)
Christopher Fauletf2824e62018-10-01 12:12:37 +02002491 goto leave;
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002492 chunk->area[chunk->data++] = '/';
Christopher Fauletf2824e62018-10-01 12:12:37 +02002493 }
Christopher Fauletf2824e62018-10-01 12:12:37 +02002494 break;
2495 }
2496 case REDIRECT_TYPE_LOCATION:
2497 default:
2498 if (rule->rdr_str) { /* this is an old "redirect" rule */
Christopher Fauletf2824e62018-10-01 12:12:37 +02002499 /* add location */
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002500 if (!chunk_memcat(chunk, rule->rdr_str, rule->rdr_len))
2501 goto leave;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002502 }
2503 else {
2504 /* add location with executing log format */
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002505 chunk->data += build_logline(s, chunk->area + chunk->data,
2506 chunk->size - chunk->data,
2507 &rule->rdr_fmt);
Christopher Fauletf2824e62018-10-01 12:12:37 +02002508 }
2509 break;
2510 }
2511
2512 if (rule->cookie_len) {
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002513 if (!chunk_memcat(chunk, "\r\nSet-Cookie: ", 14) ||
2514 !chunk_memcat(chunk, rule->cookie_str, rule->cookie_len))
2515 goto leave;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002516 }
2517
2518 /* add end of headers and the keep-alive/close status. */
2519 txn->status = rule->code;
2520 /* let's log the request time */
2521 s->logs.tv_request = now;
2522
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002523 /* FIXME: close for now, but it could be cool to handle the keep-alive here */
2524 if (unlikely(txn->flags & TX_USE_PX_CONN)) {
2525 if (!chunk_memcat(chunk, "\r\nProxy-Connection: close\r\n\r\n", 29))
2526 goto leave;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002527 } else {
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002528 if (!chunk_memcat(chunk, "\r\nConnection: close\r\n\r\n", 23))
2529 goto leave;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002530 }
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002531 htx_reply_and_close(s, txn->status, chunk);
2532 s->req.analysers &= AN_REQ_FLT_END;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002533
2534 if (!(s->flags & SF_ERR_MASK))
2535 s->flags |= SF_ERR_LOCAL;
2536 if (!(s->flags & SF_FINST_MASK))
2537 s->flags |= SF_FINST_R;
2538
2539 ret = 1;
Christopher Faulet80f14bf2018-10-24 11:02:25 +02002540 leave:
Christopher Fauletf2824e62018-10-01 12:12:37 +02002541 free_trash_chunk(chunk);
2542 return ret;
2543}
2544
2545/* This function terminates the request because it was completly analyzed or
2546 * because an error was triggered during the body forwarding.
2547 */
2548static void htx_end_request(struct stream *s)
2549{
2550 struct channel *chn = &s->req;
2551 struct http_txn *txn = s->txn;
2552
2553 DPRINTF(stderr,"[%u] %s: stream=%p states=%s,%s req->analysers=0x%08x res->analysers=0x%08x\n",
2554 now_ms, __FUNCTION__, s,
2555 h1_msg_state_str(txn->req.msg_state), h1_msg_state_str(txn->rsp.msg_state),
2556 s->req.analysers, s->res.analysers);
2557
2558 if (unlikely(txn->req.msg_state == HTTP_MSG_ERROR)) {
2559 channel_abort(chn);
2560 channel_truncate(chn);
2561 goto end;
2562 }
2563
2564 if (unlikely(txn->req.msg_state < HTTP_MSG_DONE))
2565 return;
2566
2567 if (txn->req.msg_state == HTTP_MSG_DONE) {
2568 if (txn->rsp.msg_state < HTTP_MSG_DONE) {
2569 /* The server has not finished to respond, so we
2570 * don't want to move in order not to upset it.
2571 */
2572 return;
2573 }
2574
2575 /* No need to read anymore, the request was completely parsed.
2576 * We can shut the read side unless we want to abort_on_close,
2577 * or we have a POST request. The issue with POST requests is
2578 * that some browsers still send a CRLF after the request, and
2579 * this CRLF must be read so that it does not remain in the kernel
2580 * buffers, otherwise a close could cause an RST on some systems
2581 * (eg: Linux).
2582 */
2583 if ((!(s->be->options & PR_O_ABRT_CLOSE) || (s->si[0].flags & SI_FL_CLEAN_ABRT)) &&
2584 txn->meth != HTTP_METH_POST)
2585 channel_dont_read(chn);
2586
2587 /* if the server closes the connection, we want to immediately react
2588 * and close the socket to save packets and syscalls.
2589 */
2590 s->si[1].flags |= SI_FL_NOHALF;
2591
2592 /* In any case we've finished parsing the request so we must
2593 * disable Nagle when sending data because 1) we're not going
2594 * to shut this side, and 2) the server is waiting for us to
2595 * send pending data.
2596 */
2597 chn->flags |= CF_NEVER_WAIT;
2598
2599 /* When we get here, it means that both the request and the
2600 * response have finished receiving. Depending on the connection
2601 * mode, we'll have to wait for the last bytes to leave in either
2602 * direction, and sometimes for a close to be effective.
2603 */
2604 if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_TUN) {
2605 /* Tunnel mode will not have any analyser so it needs to
2606 * poll for reads.
2607 */
2608 channel_auto_read(chn);
Christopher Faulet9768c262018-10-22 09:34:31 +02002609 if (b_data(&chn->buf))
2610 return;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002611 txn->req.msg_state = HTTP_MSG_TUNNEL;
2612 }
2613 else {
2614 /* we're not expecting any new data to come for this
2615 * transaction, so we can close it.
Christopher Faulet9768c262018-10-22 09:34:31 +02002616 *
2617 * However, there is an exception if the response
2618 * length is undefined. In this case, we need to wait
2619 * the close from the server. The response will be
2620 * switched in TUNNEL mode until the end.
Christopher Fauletf2824e62018-10-01 12:12:37 +02002621 */
2622 if (!(txn->rsp.flags & HTTP_MSGF_XFER_LEN) &&
2623 txn->rsp.msg_state != HTTP_MSG_CLOSED)
Christopher Faulet9768c262018-10-22 09:34:31 +02002624 goto check_channel_flags;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002625
2626 if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
2627 channel_shutr_now(chn);
2628 channel_shutw_now(chn);
2629 }
2630 }
Christopher Fauletf2824e62018-10-01 12:12:37 +02002631 goto check_channel_flags;
2632 }
2633
2634 if (txn->req.msg_state == HTTP_MSG_CLOSING) {
2635 http_msg_closing:
2636 /* nothing else to forward, just waiting for the output buffer
2637 * to be empty and for the shutw_now to take effect.
2638 */
2639 if (channel_is_empty(chn)) {
2640 txn->req.msg_state = HTTP_MSG_CLOSED;
2641 goto http_msg_closed;
2642 }
2643 else if (chn->flags & CF_SHUTW) {
2644 txn->req.err_state = txn->req.msg_state;
2645 txn->req.msg_state = HTTP_MSG_ERROR;
2646 goto end;
2647 }
2648 return;
2649 }
2650
2651 if (txn->req.msg_state == HTTP_MSG_CLOSED) {
2652 http_msg_closed:
Christopher Fauletf2824e62018-10-01 12:12:37 +02002653 /* if we don't know whether the server will close, we need to hard close */
2654 if (txn->rsp.flags & HTTP_MSGF_XFER_LEN)
2655 s->si[1].flags |= SI_FL_NOLINGER; /* we want to close ASAP */
Christopher Fauletf2824e62018-10-01 12:12:37 +02002656 /* see above in MSG_DONE why we only do this in these states */
2657 if ((!(s->be->options & PR_O_ABRT_CLOSE) || (s->si[0].flags & SI_FL_CLEAN_ABRT)))
2658 channel_dont_read(chn);
2659 goto end;
2660 }
2661
2662 check_channel_flags:
2663 /* Here, we are in HTTP_MSG_DONE or HTTP_MSG_TUNNEL */
2664 if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
2665 /* if we've just closed an output, let's switch */
2666 txn->req.msg_state = HTTP_MSG_CLOSING;
2667 goto http_msg_closing;
2668 }
2669
2670 end:
2671 chn->analysers &= AN_REQ_FLT_END;
2672 if (txn->req.msg_state == HTTP_MSG_TUNNEL && HAS_REQ_DATA_FILTERS(s))
2673 chn->analysers |= AN_REQ_FLT_XFER_DATA;
2674 channel_auto_close(chn);
2675 channel_auto_read(chn);
2676}
2677
2678
2679/* This function terminates the response because it was completly analyzed or
2680 * because an error was triggered during the body forwarding.
2681 */
2682static void htx_end_response(struct stream *s)
2683{
2684 struct channel *chn = &s->res;
2685 struct http_txn *txn = s->txn;
2686
2687 DPRINTF(stderr,"[%u] %s: stream=%p states=%s,%s req->analysers=0x%08x res->analysers=0x%08x\n",
2688 now_ms, __FUNCTION__, s,
2689 h1_msg_state_str(txn->req.msg_state), h1_msg_state_str(txn->rsp.msg_state),
2690 s->req.analysers, s->res.analysers);
2691
2692 if (unlikely(txn->rsp.msg_state == HTTP_MSG_ERROR)) {
Christopher Fauletf2824e62018-10-01 12:12:37 +02002693 channel_truncate(chn);
Christopher Faulet9768c262018-10-22 09:34:31 +02002694 channel_abort(&s->req);
Christopher Fauletf2824e62018-10-01 12:12:37 +02002695 goto end;
2696 }
2697
2698 if (unlikely(txn->rsp.msg_state < HTTP_MSG_DONE))
2699 return;
2700
2701 if (txn->rsp.msg_state == HTTP_MSG_DONE) {
2702 /* In theory, we don't need to read anymore, but we must
2703 * still monitor the server connection for a possible close
2704 * while the request is being uploaded, so we don't disable
2705 * reading.
2706 */
2707 /* channel_dont_read(chn); */
2708
2709 if (txn->req.msg_state < HTTP_MSG_DONE) {
2710 /* The client seems to still be sending data, probably
2711 * because we got an error response during an upload.
2712 * We have the choice of either breaking the connection
2713 * or letting it pass through. Let's do the later.
2714 */
2715 return;
2716 }
2717
2718 /* When we get here, it means that both the request and the
2719 * response have finished receiving. Depending on the connection
2720 * mode, we'll have to wait for the last bytes to leave in either
2721 * direction, and sometimes for a close to be effective.
2722 */
2723 if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_TUN) {
2724 channel_auto_read(chn);
2725 chn->flags |= CF_NEVER_WAIT;
Christopher Faulet9768c262018-10-22 09:34:31 +02002726 if (b_data(&chn->buf))
2727 return;
Christopher Fauletf2824e62018-10-01 12:12:37 +02002728 txn->rsp.msg_state = HTTP_MSG_TUNNEL;
2729 }
2730 else {
2731 /* we're not expecting any new data to come for this
2732 * transaction, so we can close it.
2733 */
2734 if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
2735 channel_shutr_now(chn);
2736 channel_shutw_now(chn);
2737 }
2738 }
2739 goto check_channel_flags;
2740 }
2741
2742 if (txn->rsp.msg_state == HTTP_MSG_CLOSING) {
2743 http_msg_closing:
2744 /* nothing else to forward, just waiting for the output buffer
2745 * to be empty and for the shutw_now to take effect.
2746 */
2747 if (channel_is_empty(chn)) {
2748 txn->rsp.msg_state = HTTP_MSG_CLOSED;
2749 goto http_msg_closed;
2750 }
2751 else if (chn->flags & CF_SHUTW) {
2752 txn->rsp.err_state = txn->rsp.msg_state;
2753 txn->rsp.msg_state = HTTP_MSG_ERROR;
2754 HA_ATOMIC_ADD(&s->be->be_counters.cli_aborts, 1);
2755 if (objt_server(s->target))
2756 HA_ATOMIC_ADD(&objt_server(s->target)->counters.cli_aborts, 1);
2757 goto end;
2758 }
2759 return;
2760 }
2761
2762 if (txn->rsp.msg_state == HTTP_MSG_CLOSED) {
2763 http_msg_closed:
2764 /* drop any pending data */
2765 channel_truncate(chn);
Christopher Faulet9768c262018-10-22 09:34:31 +02002766 channel_abort(&s->req);
Christopher Fauletf2824e62018-10-01 12:12:37 +02002767 goto end;
2768 }
2769
2770 check_channel_flags:
2771 /* Here, we are in HTTP_MSG_DONE or HTTP_MSG_TUNNEL */
2772 if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
2773 /* if we've just closed an output, let's switch */
2774 txn->rsp.msg_state = HTTP_MSG_CLOSING;
2775 goto http_msg_closing;
2776 }
2777
2778 end:
2779 chn->analysers &= AN_RES_FLT_END;
2780 if (txn->rsp.msg_state == HTTP_MSG_TUNNEL && HAS_RSP_DATA_FILTERS(s))
2781 chn->analysers |= AN_RES_FLT_XFER_DATA;
2782 channel_auto_close(chn);
2783 channel_auto_read(chn);
2784}
2785
Christopher Faulet0f226952018-10-22 09:29:56 +02002786void htx_server_error(struct stream *s, struct stream_interface *si, int err,
2787 int finst, const struct buffer *msg)
2788{
2789 channel_auto_read(si_oc(si));
2790 channel_abort(si_oc(si));
2791 channel_auto_close(si_oc(si));
2792 channel_erase(si_oc(si));
2793 channel_auto_close(si_ic(si));
2794 channel_auto_read(si_ic(si));
2795 if (msg) {
2796 struct channel *chn = si_ic(si);
2797 struct htx *htx;
2798
2799 htx = htx_from_buf(&chn->buf);
2800 htx_add_oob(htx, ist2(msg->area, msg->data));
2801 //FLT_STRM_CB(s, flt_htx_reply(s, s->txn->status, htx));
2802 b_set_data(&chn->buf, b_size(&chn->buf));
2803 c_adv(chn, htx->data);
2804 chn->total += htx->data;
2805 }
2806 if (!(s->flags & SF_ERR_MASK))
2807 s->flags |= err;
2808 if (!(s->flags & SF_FINST_MASK))
2809 s->flags |= finst;
2810}
2811
2812void htx_reply_and_close(struct stream *s, short status, struct buffer *msg)
2813{
2814 channel_auto_read(&s->req);
2815 channel_abort(&s->req);
2816 channel_auto_close(&s->req);
2817 channel_erase(&s->req);
2818 channel_truncate(&s->res);
2819
2820 s->txn->flags &= ~TX_WAIT_NEXT_RQ;
2821 if (msg) {
2822 struct channel *chn = &s->res;
2823 struct htx *htx;
2824
2825 htx = htx_from_buf(&chn->buf);
2826 htx_add_oob(htx, ist2(msg->area, msg->data));
2827 //FLT_STRM_CB(s, flt_htx_reply(s, s->txn->status, htx));
2828 b_set_data(&chn->buf, b_size(&chn->buf));
2829 c_adv(chn, htx->data);
2830 chn->total += htx->data;
2831 }
2832
2833 s->res.wex = tick_add_ifset(now_ms, s->res.wto);
2834 channel_auto_read(&s->res);
2835 channel_auto_close(&s->res);
2836 channel_shutr_now(&s->res);
2837}
2838
2839/*
2840 * Capture headers from message <htx> according to header list <cap_hdr>, and
2841 * fill the <cap> pointers appropriately.
2842 */
2843static void htx_capture_headers(struct htx *htx, char **cap, struct cap_hdr *cap_hdr)
2844{
2845 struct cap_hdr *h;
2846 int32_t pos;
2847
2848 for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
2849 struct htx_blk *blk = htx_get_blk(htx, pos);
2850 enum htx_blk_type type = htx_get_blk_type(blk);
2851 struct ist n, v;
2852
2853 if (type == HTX_BLK_EOH)
2854 break;
2855 if (type != HTX_BLK_HDR)
2856 continue;
2857
2858 n = htx_get_blk_name(htx, blk);
2859
2860 for (h = cap_hdr; h; h = h->next) {
2861 if (h->namelen && (h->namelen == n.len) &&
2862 (strncasecmp(n.ptr, h->name, h->namelen) == 0)) {
2863 if (cap[h->index] == NULL)
2864 cap[h->index] =
2865 pool_alloc(h->pool);
2866
2867 if (cap[h->index] == NULL) {
2868 ha_alert("HTTP capture : out of memory.\n");
2869 break;
2870 }
2871
2872 v = htx_get_blk_value(htx, blk);
2873 if (v.len > h->len)
2874 v.len = h->len;
2875
2876 memcpy(cap[h->index], v.ptr, v.len);
2877 cap[h->index][v.len]=0;
2878 }
2879 }
2880 }
2881}
2882
Christopher Faulet0b6bdc52018-10-24 11:05:36 +02002883/* Delete a value in a header between delimiters <from> and <next>. The header
2884 * itself is delimited by <start> and <end> pointers. The number of characters
2885 * displaced is returned, and the pointer to the first delimiter is updated if
2886 * required. The function tries as much as possible to respect the following
2887 * principles :
2888 * - replace <from> delimiter by the <next> one unless <from> points to <start>,
2889 * in which case <next> is simply removed
2890 * - set exactly one space character after the new first delimiter, unless there
2891 * are not enough characters in the block being moved to do so.
2892 * - remove unneeded spaces before the previous delimiter and after the new
2893 * one.
2894 *
2895 * It is the caller's responsibility to ensure that :
2896 * - <from> points to a valid delimiter or <start> ;
2897 * - <next> points to a valid delimiter or <end> ;
2898 * - there are non-space chars before <from>.
2899 */
2900static int htx_del_hdr_value(char *start, char *end, char **from, char *next)
2901{
2902 char *prev = *from;
2903
2904 if (prev == start) {
2905 /* We're removing the first value. eat the semicolon, if <next>
2906 * is lower than <end> */
2907 if (next < end)
2908 next++;
2909
2910 while (next < end && HTTP_IS_SPHT(*next))
2911 next++;
2912 }
2913 else {
2914 /* Remove useless spaces before the old delimiter. */
2915 while (HTTP_IS_SPHT(*(prev-1)))
2916 prev--;
2917 *from = prev;
2918
2919 /* copy the delimiter and if possible a space if we're
2920 * not at the end of the line.
2921 */
2922 if (next < end) {
2923 *prev++ = *next++;
2924 if (prev + 1 < next)
2925 *prev++ = ' ';
2926 while (next < end && HTTP_IS_SPHT(*next))
2927 next++;
2928 }
2929 }
2930 memmove(prev, next, end - next);
2931 return (prev - next);
2932}
2933
Christopher Faulet0f226952018-10-22 09:29:56 +02002934
2935/* Formats the start line of the request (without CRLF) and puts it in <str> and
2936 * return the written lenght. The line can be truncated if it exceeds <len>.
2937 */
2938static size_t htx_fmt_req_line(const union h1_sl sl, char *str, size_t len)
2939{
2940 struct ist dst = ist2(str, 0);
2941
2942 if (istcat(&dst, sl.rq.m, len) == -1)
2943 goto end;
2944 if (dst.len + 1 > len)
2945 goto end;
2946 dst.ptr[dst.len++] = ' ';
2947
2948 if (istcat(&dst, sl.rq.u, len) == -1)
2949 goto end;
2950 if (dst.len + 1 > len)
2951 goto end;
2952 dst.ptr[dst.len++] = ' ';
2953
2954 istcat(&dst, sl.rq.v, len);
2955 end:
2956 return dst.len;
2957}
2958
2959/*
2960 * Print a debug line with a start line.
2961 */
2962static void htx_debug_stline(const char *dir, struct stream *s, const union h1_sl sl)
2963{
2964 struct session *sess = strm_sess(s);
2965 int max;
2966
2967 chunk_printf(&trash, "%08x:%s.%s[%04x:%04x]: ", s->uniq_id, s->be->id,
2968 dir,
2969 objt_conn(sess->origin) ? (unsigned short)objt_conn(sess->origin)->handle.fd : -1,
2970 objt_cs(s->si[1].end) ? (unsigned short)objt_cs(s->si[1].end)->conn->handle.fd : -1);
2971
2972 max = sl.rq.m.len;
2973 UBOUND(max, trash.size - trash.data - 3);
2974 chunk_memcat(&trash, sl.rq.m.ptr, max);
2975 trash.area[trash.data++] = ' ';
2976
2977 max = sl.rq.u.len;
2978 UBOUND(max, trash.size - trash.data - 2);
2979 chunk_memcat(&trash, sl.rq.u.ptr, max);
2980 trash.area[trash.data++] = ' ';
2981
2982 max = sl.rq.v.len;
2983 UBOUND(max, trash.size - trash.data - 1);
2984 chunk_memcat(&trash, sl.rq.v.ptr, max);
2985 trash.area[trash.data++] = '\n';
2986
2987 shut_your_big_mouth_gcc(write(1, trash.area, trash.data));
2988}
2989
2990/*
2991 * Print a debug line with a header.
2992 */
2993static void htx_debug_hdr(const char *dir, struct stream *s, const struct ist n, const struct ist v)
2994{
2995 struct session *sess = strm_sess(s);
2996 int max;
2997
2998 chunk_printf(&trash, "%08x:%s.%s[%04x:%04x]: ", s->uniq_id, s->be->id,
2999 dir,
3000 objt_conn(sess->origin) ? (unsigned short)objt_conn(sess->origin)->handle.fd : -1,
3001 objt_cs(s->si[1].end) ? (unsigned short)objt_cs(s->si[1].end)->conn->handle.fd : -1);
3002
3003 max = n.len;
3004 UBOUND(max, trash.size - trash.data - 3);
3005 chunk_memcat(&trash, n.ptr, max);
3006 trash.area[trash.data++] = ':';
3007 trash.area[trash.data++] = ' ';
3008
3009 max = v.len;
3010 UBOUND(max, trash.size - trash.data - 1);
3011 chunk_memcat(&trash, v.ptr, max);
3012 trash.area[trash.data++] = '\n';
3013
3014 shut_your_big_mouth_gcc(write(1, trash.area, trash.data));
3015}
3016
3017
Christopher Fauletf4eb75d2018-10-11 15:55:07 +02003018__attribute__((constructor))
3019static void __htx_protocol_init(void)
3020{
3021}
3022
3023
3024/*
3025 * Local variables:
3026 * c-indent-level: 8
3027 * c-basic-offset: 8
3028 * End:
3029 */