* the default 'httpclose' option only sets the 'Connection:' headers

to 'close', but does not actually close any connection. The problem
  is, there are some servers which don't close the connection even if
  the proxy tells them 'Connection: close'. A workaround was added by
  the way of a new option 'forceclose' (which implies 'httpclose'),
  and which makes the proxy close the outgoing channel to the server
  once it has sent all its headers. Just don't use this with the
  'CONNECT' method of course !
This commit is contained in:
Willy TARREAU 2006-03-01 22:40:50 +01:00
parent 3481c46368
commit 767ba71444
3 changed files with 64 additions and 1 deletions

View File

@ -1757,7 +1757,7 @@ know what the client address was (eg for statistics on domains).
Last, the 'httpclose' option removes any 'Connection' header both ways, and
adds a 'Connection: close' header in each direction. This makes it easier to
disable HTTP keep-alive than the previous 4-rules block..
disable HTTP keep-alive than the previous 4-rules block.
Example :
---------
@ -1769,6 +1769,26 @@ Example :
option forwardfor
option httpclose
Note that some HTTP servers do not necessarily close the connections when they
receive the 'Connection: close', and if the client does not close either, then
the connection will be maintained up to the time-out. This translates into high
number of simultaneous sessions and high global session times in the logs. To
workaround this, a new option 'forceclose' appeared in version 1.2.9 to enforce
the closing of the outgoing server channel as soon as the server begins to
reply and only if the request buffer is empty. Note that this should NOT be
used if CONNECT requests are expected between the client and the server. The
'forceclose' option implies the 'httpclose' option.
Example :
---------
listen http_proxy 0.0.0.0:80
mode http
log global
option httplog
option dontlognull
option forwardfor
option forceclose
4.4) Load balancing with persistence
------------------------------------

View File

@ -1819,6 +1819,27 @@ Exemple :
option forwardfor
option httpclose
Notons que certains serveurs HTTP ne referment pas nécessairement la session
TCP en fin de traitement lorsqu'ils reçoivent un entête 'Connection: close',
ce qui se traduit par des grands nombres de sessions établies et des temps
globaux très longs sur les requêtes. Pour contourner ce problème, la version
1.2.9 apporte une nouvelle option 'forceclose' qui referme la connexion sortant
vers le serveur dès qu'il commence à répondre et seulement si le tampon de
requête est vide. Attention toutefois à ne PAS utiliser cette option si des
méthodes CONNECT sont attendues entre le client et le serveur. L'option
'forceclose' implique l'option 'httpclose'.
Exemple :
---------
listen http_proxy 0.0.0.0:80
mode http
log global
option httplog
option dontlognull
option forwardfor
option forceclose
4.4) Répartition avec persistence
---------------------------------
La combinaison de l'insertion de cookie avec la répartition de charge interne

View File

@ -326,6 +326,7 @@ int strlcpy2(char *dst, const char *src, int size) {
#define PR_O_TCP_CLI_KA 0x00040000 /* enable TCP keep-alive on client-side sessions */
#define PR_O_TCP_SRV_KA 0x00080000 /* enable TCP keep-alive on server-side sessions */
#define PR_O_USE_ALL_BK 0x00100000 /* load-balance between backup servers */
#define PR_O_FORCE_CLO 0x00200000 /* enforce the connection close immediately after server response */
/* various session flags */
#define SN_DIRECT 0x00000001 /* connection made on the server matching the client cookie */
@ -4234,6 +4235,24 @@ int process_srv(struct session *t) {
rep->rlim = rep->data + BUFSIZE; /* no more rewrite needed */
t->logs.t_data = tv_diff(&t->logs.tv_accept, &now);
/* client connection already closed or option 'httpclose' required :
* we close the server's outgoing connection right now.
*/
if ((req->l == 0) &&
(c == CL_STSHUTR || c == CL_STCLOSE || t->proxy->options & PR_O_FORCE_CLO)) {
FD_CLR(t->srv_fd, StaticWriteEvent);
tv_eternity(&t->swexpire);
/* We must ensure that the read part is still alive when switching
* to shutw */
FD_SET(t->srv_fd, StaticReadEvent);
if (t->proxy->srvtimeout)
tv_delayfrom(&t->srexpire, &now, t->proxy->srvtimeout);
shutdown(t->srv_fd, SHUT_WR);
t->srv_state = SV_STSHUTW;
}
/* if the user wants to log as soon as possible, without counting
bytes from the server, then this is the right moment. */
if (t->proxy->to_log && !(t->logs.logwait & LW_BYTES)) {
@ -6574,6 +6593,9 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
else if (!strcmp(args[1], "httpclose"))
/* force connection: close in both directions in HTTP mode */
curproxy->options |= PR_O_HTTP_CLOSE;
else if (!strcmp(args[1], "forceclose"))
/* force connection: close in both directions in HTTP mode and enforce end of session */
curproxy->options |= PR_O_FORCE_CLO | PR_O_HTTP_CLOSE;
else if (!strcmp(args[1], "checkcache"))
/* require examination of cacheability of the 'set-cookie' field */
curproxy->options |= PR_O_CHK_CACHE;