haproxy/include/types/session.h

175 lines
8.5 KiB
C
Raw Normal View History

/*
[MAJOR] http: completely process the "connection" header Up to now, we only had a flag in the session indicating if it had to work in "connection: close" mode. This is not at all compatible with keep-alive. Now we ensure that both sides of a connection act independantly and only relative to the transaction. The HTTP version of the request and response is also correctly considered. The connection already knows several modes : - tunnel (CONNECT or no option in the config) - keep-alive (when permitted by configuration) - server-close (close the server side, not the client) - close (close both sides) This change carefully detects all situations to find whether a request can be fully processed in its mode according to the configuration. Then the response is also checked and tested to fix corner cases which can happen with different HTTP versions on both sides (eg: a 1.0 client asks for explicit keep-alive, and the server responds with 1.1 without a header). The mode is selected by a capability elimination algorithm which automatically focuses on the least capable agent between the client, the frontend, the backend and the server. This ensures we won't get undesired situtations where one of the 4 "agents" is not able to process a transaction. No "Connection: close" header will be added anymore to HTTP/1.0 requests or responses since they're already in close mode. The server-close mode is still not completely implemented. The response needs to be rewritten as keep-alive before being sent to the client if the connection was already in server-close (which implies the request was in keep-alive) and if the response has a content-length or a transfer-encoding (but only if client supports 1.1). A later improvement in server-close mode would probably be to detect some situations where it's interesting to close the response (eg: redirections with remote locations). But even then, the client might close by itself. It's also worth noting that in tunnel mode, no connection header is affected in either direction. A tunnelled connection should theorically be notified at the session level, but this is useless since by definition there will not be any more requests on it. Thus, we don't need to add a flag into the session right now.
2009-12-21 14:11:07 -05:00
* include/types/session.h
* This file defines everything related to sessions.
*
* Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
[MAJOR] http: completely process the "connection" header Up to now, we only had a flag in the session indicating if it had to work in "connection: close" mode. This is not at all compatible with keep-alive. Now we ensure that both sides of a connection act independantly and only relative to the transaction. The HTTP version of the request and response is also correctly considered. The connection already knows several modes : - tunnel (CONNECT or no option in the config) - keep-alive (when permitted by configuration) - server-close (close the server side, not the client) - close (close both sides) This change carefully detects all situations to find whether a request can be fully processed in its mode according to the configuration. Then the response is also checked and tested to fix corner cases which can happen with different HTTP versions on both sides (eg: a 1.0 client asks for explicit keep-alive, and the server responds with 1.1 without a header). The mode is selected by a capability elimination algorithm which automatically focuses on the least capable agent between the client, the frontend, the backend and the server. This ensures we won't get undesired situtations where one of the 4 "agents" is not able to process a transaction. No "Connection: close" header will be added anymore to HTTP/1.0 requests or responses since they're already in close mode. The server-close mode is still not completely implemented. The response needs to be rewritten as keep-alive before being sent to the client if the connection was already in server-close (which implies the request was in keep-alive) and if the response has a content-length or a transfer-encoding (but only if client supports 1.1). A later improvement in server-close mode would probably be to detect some situations where it's interesting to close the response (eg: redirections with remote locations). But even then, the client might close by itself. It's also worth noting that in tunnel mode, no connection header is affected in either direction. A tunnelled connection should theorically be notified at the session level, but this is useless since by definition there will not be any more requests on it. Thus, we don't need to add a flag into the session right now.
2009-12-21 14:11:07 -05:00
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _TYPES_SESSION_H
#define _TYPES_SESSION_H
#include <sys/time.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <common/config.h>
#include <common/mini-clist.h>
#include <types/channel.h>
MEDIUM: HTTP compression (zlib library support) This commit introduces HTTP compression using the zlib library. http_response_forward_body has been modified to call the compression functions. This feature includes 3 algorithms: identity, gzip and deflate: * identity: this is mostly for debugging, and it was useful for developping the compression feature. With Content-Length in input, it is making each chunk with the data available in the current buffer. With chunks in input, it is rechunking, the output chunks will be bigger or smaller depending of the size of the input chunk and the size of the buffer. Identity does not apply any change on data. * gzip: same as identity, but applying a gzip compression. The data are deflated using the Z_NO_FLUSH flag in zlib. When there is no more data in the input buffer, it flushes the data in the output buffer (Z_SYNC_FLUSH). At the end of data, when it receives the last chunk in input, or when there is no more data to read, it writes the end of data with Z_FINISH and the ending chunk. * deflate: same as gzip, but with deflate algorithm and zlib format. Note that this algorithm has ambiguous support on many browsers and no support at all from recent ones. It is strongly recommended not to use it for anything else than experimentation. You can't choose the compression ratio at the moment, it will be set to Z_BEST_SPEED (1), as tests have shown very little benefit in terms of compression ration when going above for HTML contents, at the cost of a massive CPU impact. Compression will be activated depending of the Accept-Encoding request header. With identity, it does not take care of that header. To build HAProxy with zlib support, use USE_ZLIB=1 in the make parameters. This work was initially started by David Du Colombier at Exceliance.
2012-10-23 04:25:10 -04:00
#include <types/compression.h>
#include <types/hlua.h>
#include <types/obj_type.h>
#include <types/proto_http.h>
#include <types/proxy.h>
#include <types/queue.h>
#include <types/server.h>
[MAJOR] rework of the server FSM srv_state has been removed from HTTP state machines, and states have been split in either TCP states or analyzers. For instance, the TARPIT state has just become a simple analyzer. New flags have been added to the struct buffer to compensate this. The high-level stream processors sometimes need to force a disconnection without touching a file-descriptor (eg: report an error). But if they touched BF_SHUTW or BF_SHUTR, the file descriptor would not be closed. Thus, the two SHUT?_NOW flags have been added so that an application can request a forced close which the stream interface will be forced to obey. During this change, a new BF_HIJACK flag was added. It will be used for data generation, eg during a stats dump. It prevents the producer on a buffer from sending data into it. BF_SHUTR_NOW /* the producer must shut down for reads ASAP */ BF_SHUTW_NOW /* the consumer must shut down for writes ASAP */ BF_HIJACK /* the producer is temporarily replaced */ BF_SHUTW_NOW has precedence over BF_HIJACK. BF_HIJACK has precedence over BF_MAY_FORWARD (so that it does not need it). New functions buffer_shutr_now(), buffer_shutw_now(), buffer_abort() are provided to manipulate BF_SHUT* flags. A new type "stream_interface" has been added to describe both sides of a buffer. A stream interface has states and error reporting. The session now has two stream interfaces (one per side). Each buffer has stream_interface pointers to both consumer and producer sides. The server-side file descriptor has moved to its stream interface, so that even the buffer has access to it. process_srv() has been split into three parts : - tcp_get_connection() obtains a connection to the server - tcp_connection_failed() tests if a previously attempted connection has succeeded or not. - process_srv_data() only manages the data phase, and in this sense should be roughly equivalent to process_cli. Little code has been removed, and a lot of old code has been left in comments for now.
2008-10-19 01:30:41 -04:00
#include <types/stream_interface.h>
#include <types/task.h>
#include <types/stick_table.h>
/* various session flags, bits values 0x01 to 0x100 (shift 0) */
#define SN_DIRECT 0x00000001 /* connection made on the server matching the client cookie */
#define SN_ASSIGNED 0x00000002 /* no need to assign a server to this session */
#define SN_ADDR_SET 0x00000004 /* this session's server address has been set */
#define SN_BE_ASSIGNED 0x00000008 /* a backend was assigned. Conns are accounted. */
[MAJOR] http: completely process the "connection" header Up to now, we only had a flag in the session indicating if it had to work in "connection: close" mode. This is not at all compatible with keep-alive. Now we ensure that both sides of a connection act independantly and only relative to the transaction. The HTTP version of the request and response is also correctly considered. The connection already knows several modes : - tunnel (CONNECT or no option in the config) - keep-alive (when permitted by configuration) - server-close (close the server side, not the client) - close (close both sides) This change carefully detects all situations to find whether a request can be fully processed in its mode according to the configuration. Then the response is also checked and tested to fix corner cases which can happen with different HTTP versions on both sides (eg: a 1.0 client asks for explicit keep-alive, and the server responds with 1.1 without a header). The mode is selected by a capability elimination algorithm which automatically focuses on the least capable agent between the client, the frontend, the backend and the server. This ensures we won't get undesired situtations where one of the 4 "agents" is not able to process a transaction. No "Connection: close" header will be added anymore to HTTP/1.0 requests or responses since they're already in close mode. The server-close mode is still not completely implemented. The response needs to be rewritten as keep-alive before being sent to the client if the connection was already in server-close (which implies the request was in keep-alive) and if the response has a content-length or a transfer-encoding (but only if client supports 1.1). A later improvement in server-close mode would probably be to detect some situations where it's interesting to close the response (eg: redirections with remote locations). But even then, the client might close by itself. It's also worth noting that in tunnel mode, no connection header is affected in either direction. A tunnelled connection should theorically be notified at the session level, but this is useless since by definition there will not be any more requests on it. Thus, we don't need to add a flag into the session right now.
2009-12-21 14:11:07 -05:00
#define SN_FORCE_PRST 0x00000010 /* force persistence here, even if server is down */
#define SN_MONITOR 0x00000020 /* this session comes from a monitoring system */
#define SN_CURR_SESS 0x00000040 /* a connection is currently being counted on the server */
#define SN_INITIALIZED 0x00000080 /* the session was fully initialized */
#define SN_REDISP 0x00000100 /* set if this session was redispatched from one server to another */
#define SN_CONN_TAR 0x00000200 /* set if this session is turning around before reconnecting */
#define SN_REDIRECTABLE 0x00000400 /* set if this session is redirectable (GET or HEAD) */
#define SN_TUNNEL 0x00000800 /* tunnel-mode session, nothing to catch after data */
/* session termination conditions, bits values 0x1000 to 0x7000 (0-9 shift 12) */
#define SN_ERR_NONE 0x00000000 /* normal end of request */
#define SN_ERR_LOCAL 0x00001000 /* the proxy locally processed this request => not an error */
#define SN_ERR_CLITO 0x00002000 /* client time-out */
#define SN_ERR_CLICL 0x00003000 /* client closed (read/write error) */
#define SN_ERR_SRVTO 0x00004000 /* server time-out, connect time-out */
#define SN_ERR_SRVCL 0x00005000 /* server closed (connect/read/write error) */
#define SN_ERR_PRXCOND 0x00006000 /* the proxy decided to close (deny...) */
#define SN_ERR_RESOURCE 0x00007000 /* the proxy encountered a lack of a local resources (fd, mem, ...) */
#define SN_ERR_INTERNAL 0x00008000 /* the proxy encountered an internal error */
#define SN_ERR_DOWN 0x00009000 /* the proxy killed a session because the backend became unavailable */
#define SN_ERR_KILLED 0x0000a000 /* the proxy killed a session because it was asked to do so */
#define SN_ERR_UP 0x0000b000 /* the proxy killed a session because a preferred backend became available */
#define SN_ERR_MASK 0x0000f000 /* mask to get only session error flags */
#define SN_ERR_SHIFT 12 /* bit shift */
/* session state at termination, bits values 0x10000 to 0x70000 (0-7 shift 16) */
#define SN_FINST_R 0x00010000 /* session ended during client request */
#define SN_FINST_C 0x00020000 /* session ended during server connect */
#define SN_FINST_H 0x00030000 /* session ended during server headers */
#define SN_FINST_D 0x00040000 /* session ended during data phase */
#define SN_FINST_L 0x00050000 /* session ended while pushing last data to client */
#define SN_FINST_Q 0x00060000 /* session ended while waiting in queue for a server slot */
#define SN_FINST_T 0x00070000 /* session ended tarpitted */
#define SN_FINST_MASK 0x00070000 /* mask to get only final session state flags */
#define SN_FINST_SHIFT 16 /* bit shift */
#define SN_IGNORE_PRST 0x00080000 /* ignore persistence */
#define SN_COMP_READY 0x00100000 /* the compression is initialized */
#define SN_SRV_REUSED 0x00200000 /* the server-side connection was reused */
/*
* Note: some session flags have dependencies :
* - SN_DIRECT cannot exist without SN_ASSIGNED, because a server is
* immediately assigned when SN_DIRECT is determined. Both must be cleared
* when clearing SN_DIRECT (eg: redispatch).
* - ->srv has no meaning without SN_ASSIGNED and must not be checked without
* it. ->target may be used to check previous ->srv after a failed connection attempt.
* - a session being processed has srv_conn set.
* - srv_conn might remain after SN_DIRECT has been reset, but the assigned
* server should eventually be released.
*/
struct session {
int flags; /* some flags describing the session */
unsigned int uniq_id; /* unique ID used for the traces */
enum obj_type *target; /* target to use for this session ; for mini-sess: incoming connection */
struct channel *req; /* request buffer */
struct channel *rep; /* response buffer */
struct proxy *fe; /* the proxy this session depends on for the client side */
struct proxy *be; /* the proxy this session depends on for the server side */
struct listener *listener; /* the listener by which the request arrived */
struct server *srv_conn; /* session already has a slot on a server and is not in queue */
struct pendconn *pend_pos; /* if not NULL, points to the position in the pending queue */
struct http_txn txn; /* current HTTP transaction being processed. Should become a list. */
struct task *task; /* the task associated with this session */
struct list list; /* position in global sessions list */
struct list by_srv; /* position in server session list */
struct list back_refs; /* list of users tracking this session */
struct list buffer_wait; /* position in the list of sessions waiting for a buffer */
struct {
struct stksess *ts;
struct stktable *table;
} store[8]; /* tracked stickiness values to store */
int store_count;
/* 4 unused bytes here */
struct stkctr stkctr[MAX_SESS_STKCTR]; /* stick counters */
struct stream_interface si[2]; /* client and server stream interfaces */
struct {
int logwait; /* log fields waiting to be collected : LW_* */
int level; /* log level to force + 1 if > 0, -1 = no log */
struct timeval accept_date; /* date of the accept() in user date */
struct timeval tv_accept; /* date of the accept() in internal date (monotonic) */
struct timeval tv_request; /* date the request arrives, {0,0} if never occurs */
long t_queue; /* delay before the session gets out of the connect queue, -1 if never occurs */
long t_connect; /* delay before the connect() to the server succeeds, -1 if never occurs */
long t_data; /* delay before the first data byte from the server ... */
unsigned long t_close; /* total session duration */
unsigned long srv_queue_size; /* number of sessions waiting for a connect slot on this server at accept() time (in direct assignment) */
unsigned long prx_queue_size; /* overall number of sessions waiting for a connect slot on this instance at accept() time */
long long bytes_in; /* number of bytes transferred from the client to the server */
long long bytes_out; /* number of bytes transferred from the server to the client */
} logs;
void (*do_log)(struct session *s); /* the function to call in order to log (or NULL) */
void (*srv_error)(struct session *s, /* the function to call upon unrecoverable server errors (or NULL) */
struct stream_interface *si);
struct comp_ctx *comp_ctx; /* HTTP compression context */
MEDIUM: HTTP compression (zlib library support) This commit introduces HTTP compression using the zlib library. http_response_forward_body has been modified to call the compression functions. This feature includes 3 algorithms: identity, gzip and deflate: * identity: this is mostly for debugging, and it was useful for developping the compression feature. With Content-Length in input, it is making each chunk with the data available in the current buffer. With chunks in input, it is rechunking, the output chunks will be bigger or smaller depending of the size of the input chunk and the size of the buffer. Identity does not apply any change on data. * gzip: same as identity, but applying a gzip compression. The data are deflated using the Z_NO_FLUSH flag in zlib. When there is no more data in the input buffer, it flushes the data in the output buffer (Z_SYNC_FLUSH). At the end of data, when it receives the last chunk in input, or when there is no more data to read, it writes the end of data with Z_FINISH and the ending chunk. * deflate: same as gzip, but with deflate algorithm and zlib format. Note that this algorithm has ambiguous support on many browsers and no support at all from recent ones. It is strongly recommended not to use it for anything else than experimentation. You can't choose the compression ratio at the moment, it will be set to Z_BEST_SPEED (1), as tests have shown very little benefit in terms of compression ration when going above for HTML contents, at the cost of a massive CPU impact. Compression will be activated depending of the Accept-Encoding request header. With identity, it does not take care of that header. To build HAProxy with zlib support, use USE_ZLIB=1 in the make parameters. This work was initially started by David Du Colombier at Exceliance.
2012-10-23 04:25:10 -04:00
struct comp_algo *comp_algo; /* HTTP compression algorithm if not NULL */
char *unique_id; /* custom unique ID */
/* These two pointers are used to resume the execution of the rule lists. */
struct list *current_rule_list; /* this is used to store the current executed rule list. */
struct list *current_rule; /* this is used to store the current rule to be resumed. */
struct hlua hlua; /* lua runtime context */
};
#endif /* _TYPES_SESSION_H */
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/