~ubuntu-branches/ubuntu/trusty/haproxy/trusty-backports

« back to all changes in this revision

Viewing changes to src/proto_http.c

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Cornet
  • Date: 2009-06-26 00:11:01 UTC
  • mfrom: (1.1.6 upstream) (2.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090626001101-qo261ke2mjh3d8cn
* New Upstream Version (Closes: #534583).
* Add contrib directory in docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <common/memory.h>
31
31
#include <common/mini-clist.h>
32
32
#include <common/standard.h>
 
33
#include <common/ticks.h>
33
34
#include <common/time.h>
34
35
#include <common/uri_auth.h>
35
36
#include <common/version.h>
36
37
 
37
 
#include <types/acl.h>
38
38
#include <types/capture.h>
39
 
#include <types/client.h>
40
39
#include <types/global.h>
41
 
#include <types/httperr.h>
42
 
#include <types/polling.h>
43
 
#include <types/proxy.h>
44
 
#include <types/server.h>
45
40
 
46
41
#include <proto/acl.h>
47
42
#include <proto/backend.h>
48
43
#include <proto/buffers.h>
 
44
#include <proto/client.h>
49
45
#include <proto/dumpstats.h>
50
46
#include <proto/fd.h>
51
47
#include <proto/log.h>
52
48
#include <proto/hdr_idx.h>
 
49
#include <proto/proto_tcp.h>
53
50
#include <proto/proto_http.h>
 
51
#include <proto/proxy.h>
54
52
#include <proto/queue.h>
55
 
#include <proto/senddata.h>
 
53
#include <proto/server.h>
56
54
#include <proto/session.h>
 
55
#include <proto/stream_interface.h>
 
56
#include <proto/stream_sock.h>
57
57
#include <proto/task.h>
58
58
 
59
59
#ifdef CONFIG_HAP_TCPSPLICE
88
88
        .len = sizeof(HTTP_200)-1
89
89
};
90
90
 
 
91
const char *HTTP_301 =
 
92
        "HTTP/1.0 301 Moved Permantenly\r\n"
 
93
        "Cache-Control: no-cache\r\n"
 
94
        "Connection: close\r\n"
 
95
        "Location: "; /* not terminated since it will be concatenated with the URL */
 
96
 
91
97
const char *HTTP_302 =
92
98
        "HTTP/1.0 302 Found\r\n"
93
99
        "Cache-Control: no-cache\r\n"
363
369
 
364
370
 
365
371
#ifdef DEBUG_FULL
366
 
static char *cli_stnames[5] = {"HDR", "DAT", "SHR", "SHW", "CLS" };
367
 
static char *srv_stnames[7] = {"IDL", "CON", "HDR", "DAT", "SHR", "SHW", "CLS" };
 
372
static char *cli_stnames[4] = { "DAT", "SHR", "SHW", "CLS" };
368
373
#endif
369
374
 
370
 
static void http_sess_log(struct session *s);
371
 
 
372
375
/*
373
376
 * Adds a header and its CRLF at the tail of buffer <b>, just before the last
374
377
 * CRLF. Text length is measured first, so it cannot be NULL.
465
468
                      const char *sol, struct hdr_idx *idx,
466
469
                      struct hdr_ctx *ctx)
467
470
{
468
 
        __label__ return_hdr, next_hdr;
469
471
        const char *eol, *sov;
470
472
        int cur_idx;
471
473
 
535
537
        return http_find_header2(name, strlen(name), sol, idx, ctx);
536
538
}
537
539
 
538
 
/* This function turns the server state into the SV_STCLOSE, and sets
539
 
 * indicators accordingly. Note that if <status> is 0, or if the message
540
 
 * pointer is NULL, then no message is returned.
 
540
/* This function handles a server error at the stream interface level. The
 
541
 * stream interface is assumed to be already in a closed state. An optional
 
542
 * message is copied into the input buffer, and an HTTP status code stored.
 
543
 * The error flags are set to the values in arguments. Any pending request
 
544
 * in this buffer will be lost.
541
545
 */
542
 
void srv_close_with_err(struct session *t, int err, int finst,
543
 
                        int status, const struct chunk *msg)
 
546
static void http_server_error(struct session *t, struct stream_interface *si,
 
547
                              int err, int finst, int status, const struct chunk *msg)
544
548
{
545
 
        t->srv_state = SV_STCLOSE;
 
549
        buffer_erase(si->ob);
 
550
        buffer_erase(si->ib);
 
551
        buffer_write_ena(si->ib);
546
552
        if (status > 0 && msg) {
547
553
                t->txn.status = status;
548
 
                if (t->fe->mode == PR_MODE_HTTP)
549
 
                        client_return(t, msg);
 
554
                buffer_write(si->ib, msg->str, msg->len);
550
555
        }
551
556
        if (!(t->flags & SN_ERR_MASK))
552
557
                t->flags |= err;
640
645
        return ptr;
641
646
}
642
647
 
643
 
/* Processes the client and server jobs of a session task, then
644
 
 * puts it back to the wait queue in a clean state, or
645
 
 * cleans up its resources if it must be deleted. Returns
646
 
 * the time the task accepts to wait, or TIME_ETERNITY for
647
 
 * infinity.
648
 
 */
649
 
void process_session(struct task *t, struct timeval *next)
650
 
{
651
 
        struct session *s = t->context;
652
 
        int fsm_resync = 0;
653
 
 
654
 
        do {
655
 
                fsm_resync = 0;
656
 
                //fprintf(stderr,"before_cli:cli=%d, srv=%d\n", s->cli_state, s->srv_state);
657
 
                fsm_resync |= process_cli(s);
658
 
                //fprintf(stderr,"cli/srv:cli=%d, srv=%d\n", s->cli_state, s->srv_state);
659
 
                fsm_resync |= process_srv(s);
660
 
                //fprintf(stderr,"after_srv:cli=%d, srv=%d\n", s->cli_state, s->srv_state);
661
 
        } while (fsm_resync);
662
 
 
663
 
        if (likely(s->cli_state != CL_STCLOSE || s->srv_state != SV_STCLOSE)) {
664
 
 
665
 
                if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED))
666
 
                        session_process_counters(s);
667
 
 
668
 
                s->req->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE;
669
 
                s->rep->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE;
670
 
 
671
 
                tv_min(&t->expire, &s->req->rex, &s->req->wex);
672
 
                tv_bound(&t->expire, &s->req->cex);
673
 
                tv_bound(&t->expire, &s->rep->rex);
674
 
                tv_bound(&t->expire, &s->rep->wex);
675
 
                if (s->cli_state == CL_STHEADERS)
676
 
                        tv_bound(&t->expire, &s->txn.exp);
677
 
 
678
 
                /* restore t to its place in the task list */
679
 
                task_queue(t);
680
 
 
681
 
#ifdef DEBUG_FULL
682
 
                /* DEBUG code : this should never ever happen, otherwise it indicates
683
 
                 * that a task still has something to do and will provoke a quick loop.
684
 
                 */
685
 
                if (tv_ms_remain2(&now, &t->expire) <= 0)
686
 
                        exit(100);
687
 
#endif
688
 
                *next = t->expire;
689
 
                return; /* nothing more to do */
690
 
        }
691
 
 
692
 
        s->fe->feconn--;
693
 
        if (s->flags & SN_BE_ASSIGNED)
694
 
                s->be->beconn--;
695
 
        actconn--;
696
 
    
697
 
        if (unlikely((global.mode & MODE_DEBUG) &&
698
 
                     (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
699
 
                int len;
700
 
                len = sprintf(trash, "%08x:%s.closed[%04x:%04x]\n",
701
 
                              s->uniq_id, s->be->id,
702
 
                              (unsigned short)s->cli_fd, (unsigned short)s->srv_fd);
703
 
                write(1, trash, len);
704
 
        }
705
 
 
706
 
        s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now);
707
 
        session_process_counters(s);
708
 
 
709
 
        /* let's do a final log if we need it */
710
 
        if (s->logs.logwait && 
711
 
            !(s->flags & SN_MONITOR) &&
712
 
            (!(s->fe->options & PR_O_NULLNOLOG) || s->req->total)) {
713
 
                if (s->fe->to_log & LW_REQ)
714
 
                        http_sess_log(s);
715
 
                else
716
 
                        tcp_sess_log(s);
717
 
        }
718
 
 
719
 
        /* the task MUST not be in the run queue anymore */
720
 
        task_delete(t);
721
 
        session_free(s);
722
 
        task_free(t);
723
 
        tv_eternity(next);
724
 
}
725
 
 
 
648
/* Returns a 302 for a redirectable request. This may only be called just after
 
649
 * the stream interface has moved to SI_ST_ASS. Unprocessable requests are
 
650
 * left unchanged and will follow normal proxy processing.
 
651
 */
 
652
void perform_http_redirect(struct session *s, struct stream_interface *si)
 
653
{
 
654
        struct http_txn *txn;
 
655
        struct chunk rdr;
 
656
        char *path;
 
657
        int len;
 
658
 
 
659
        /* 1: create the response header */
 
660
        rdr.len = strlen(HTTP_302);
 
661
        rdr.str = trash;
 
662
        memcpy(rdr.str, HTTP_302, rdr.len);
 
663
 
 
664
        /* 2: add the server's prefix */
 
665
        if (rdr.len + s->srv->rdr_len > sizeof(trash))
 
666
                return;
 
667
 
 
668
        memcpy(rdr.str + rdr.len, s->srv->rdr_pfx, s->srv->rdr_len);
 
669
        rdr.len += s->srv->rdr_len;
 
670
 
 
671
        /* 3: add the request URI */
 
672
        txn = &s->txn;
 
673
        path = http_get_path(txn);
 
674
        if (!path)
 
675
                return;
 
676
 
 
677
        len = txn->req.sl.rq.u_l + (txn->req.sol+txn->req.sl.rq.u) - path;
 
678
        if (rdr.len + len > sizeof(trash) - 4) /* 4 for CRLF-CRLF */
 
679
                return;
 
680
 
 
681
        memcpy(rdr.str + rdr.len, path, len);
 
682
        rdr.len += len;
 
683
        memcpy(rdr.str + rdr.len, "\r\n\r\n", 4);
 
684
        rdr.len += 4;
 
685
 
 
686
        /* prepare to return without error. */
 
687
        si->shutr(si);
 
688
        si->shutw(si);
 
689
        si->err_type = SI_ET_NONE;
 
690
        si->err_loc  = NULL;
 
691
        si->state    = SI_ST_CLO;
 
692
 
 
693
        /* send the message */
 
694
        http_server_error(s, si, SN_ERR_PRXCOND, SN_FINST_C, 302, &rdr);
 
695
 
 
696
        /* FIXME: we should increase a counter of redirects per server and per backend. */
 
697
        if (s->srv)
 
698
                srv_inc_sess_ctr(s->srv);
 
699
}
 
700
 
 
701
/* Return the error message corresponding to si->err_type. It is assumed
 
702
 * that the server side is closed. Note that err_type is actually a
 
703
 * bitmask, where almost only aborts may be cumulated with other
 
704
 * values. We consider that aborted operations are more important
 
705
 * than timeouts or errors due to the fact that nobody else in the
 
706
 * logs might explain incomplete retries. All others should avoid
 
707
 * being cumulated. It should normally not be possible to have multiple
 
708
 * aborts at once, but just in case, the first one in sequence is reported.
 
709
 */
 
710
void http_return_srv_error(struct session *s, struct stream_interface *si)
 
711
{
 
712
        int err_type = si->err_type;
 
713
 
 
714
        if (err_type & SI_ET_QUEUE_ABRT)
 
715
                http_server_error(s, si, SN_ERR_CLICL, SN_FINST_Q,
 
716
                                  503, error_message(s, HTTP_ERR_503));
 
717
        else if (err_type & SI_ET_CONN_ABRT)
 
718
                http_server_error(s, si, SN_ERR_CLICL, SN_FINST_C,
 
719
                                  503, error_message(s, HTTP_ERR_503));
 
720
        else if (err_type & SI_ET_QUEUE_TO)
 
721
                http_server_error(s, si, SN_ERR_SRVTO, SN_FINST_Q,
 
722
                                  503, error_message(s, HTTP_ERR_503));
 
723
        else if (err_type & SI_ET_QUEUE_ERR)
 
724
                http_server_error(s, si, SN_ERR_SRVCL, SN_FINST_Q,
 
725
                                  503, error_message(s, HTTP_ERR_503));
 
726
        else if (err_type & SI_ET_CONN_TO)
 
727
                http_server_error(s, si, SN_ERR_SRVTO, SN_FINST_C,
 
728
                                  503, error_message(s, HTTP_ERR_503));
 
729
        else if (err_type & SI_ET_CONN_ERR)
 
730
                http_server_error(s, si, SN_ERR_SRVCL, SN_FINST_C,
 
731
                                  503, error_message(s, HTTP_ERR_503));
 
732
        else /* SI_ET_CONN_OTHER and others */
 
733
                http_server_error(s, si, SN_ERR_INTERNAL, SN_FINST_C,
 
734
                                  500, error_message(s, HTTP_ERR_500));
 
735
}
726
736
 
727
737
extern const char sess_term_cond[8];
728
738
extern const char sess_fin_state[8];
738
748
 * send a log for the session when we have enough info about it.
739
749
 * Will not log if the frontend has no log defined.
740
750
 */
741
 
static void http_sess_log(struct session *s)
 
751
void http_sess_log(struct session *s)
742
752
{
743
753
        char pn[INET6_ADDRSTRLEN + strlen(":65535")];
744
754
        struct proxy *fe = s->fe;
745
755
        struct proxy *be = s->be;
746
756
        struct proxy *prx_log;
747
757
        struct http_txn *txn = &s->txn;
748
 
        int tolog;
 
758
        int tolog, level, err;
749
759
        char *uri, *h;
750
760
        char *svid;
751
761
        struct tm tm;
753
763
        int t_request;
754
764
        int hdr;
755
765
 
 
766
        /* if we don't want to log normal traffic, return now */
 
767
        err = (s->flags & (SN_ERR_MASK | SN_REDISP)) ||
 
768
                (s->conn_retries != be->conn_retries) ||
 
769
                txn->status >= 500;
 
770
        if (!err && (fe->options2 & PR_O2_NOLOGNORM))
 
771
                return;
 
772
 
756
773
        if (fe->logfac1 < 0 && fe->logfac2 < 0)
757
774
                return;
758
775
        prx_log = fe;
766
783
                          (const void *)&((struct sockaddr_in6 *)(&s->cli_addr))->sin6_addr,
767
784
                          pn, sizeof(pn));
768
785
 
769
 
        get_localtime(s->logs.tv_accept.tv_sec, &tm);
 
786
        get_localtime(s->logs.accept_date.tv_sec, &tm);
770
787
 
771
788
        /* FIXME: let's limit ourselves to frontend logging for now. */
772
789
        tolog = fe->to_log;
820
837
        if (tv_isge(&s->logs.tv_request, &s->logs.tv_accept))
821
838
                t_request = tv_ms_elapsed(&s->logs.tv_accept, &s->logs.tv_request);
822
839
 
823
 
        send_log(prx_log, LOG_INFO,
 
840
        level = LOG_INFO;
 
841
        if (err && (fe->options2 & PR_O2_LOGERRORS))
 
842
                level = LOG_ERR;
 
843
 
 
844
        send_log(prx_log, level,
824
845
                 "%s:%d [%02d/%s/%04d:%02d:%02d:%02d.%03d]"
825
 
                 " %s %s/%s %d/%d/%d/%d/%s%d %d %s%lld"
826
 
                 " %s %s %c%c%c%c %d/%d/%d/%d/%s%u %d/%d%s\n",
 
846
                 " %s %s/%s %d/%ld/%ld/%ld/%s%ld %d %s%lld"
 
847
                 " %s %s %c%c%c%c %d/%d/%d/%d/%s%u %ld/%ld%s\n",
827
848
                 pn,
828
849
                 (s->cli_addr.ss_family == AF_INET) ?
829
850
                 ntohs(((struct sockaddr_in *)&s->cli_addr)->sin_port) :
830
851
                 ntohs(((struct sockaddr_in6 *)&s->cli_addr)->sin6_port),
831
852
                 tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
832
 
                 tm.tm_hour, tm.tm_min, tm.tm_sec, s->logs.tv_accept.tv_usec/1000,
 
853
                 tm.tm_hour, tm.tm_min, tm.tm_sec, (int)s->logs.accept_date.tv_usec/1000,
833
854
                 fe->id, be->id, svid,
834
855
                 t_request,
835
856
                 (s->logs.t_queue >= 0) ? s->logs.t_queue - t_request : -1,
946
967
                               unsigned int state, const char *ptr, const char *end,
947
968
                               char **ret_ptr, unsigned int *ret_state)
948
969
{
949
 
        __label__
950
 
                http_msg_rpver,
951
 
                http_msg_rpver_sp,
952
 
                http_msg_rpcode,
953
 
                http_msg_rpcode_sp,
954
 
                http_msg_rpreason,
955
 
                http_msg_rpline_eol,
956
 
                http_msg_ood,     /* out of data */
957
 
                http_msg_invalid;
958
 
 
959
970
        switch (state)  {
960
971
        http_msg_rpver:
961
972
        case HTTP_MSG_RPVER:
966
977
                        msg->sl.st.v_l = (ptr - msg_buf) - msg->som;
967
978
                        EAT_AND_JUMP_OR_RETURN(http_msg_rpver_sp, HTTP_MSG_RPVER_SP);
968
979
                }
969
 
                goto http_msg_invalid;
970
 
                
 
980
                state = HTTP_MSG_ERROR;
 
981
                break;
 
982
 
971
983
        http_msg_rpver_sp:
972
984
        case HTTP_MSG_RPVER_SP:
973
985
                if (likely(!HTTP_IS_LWS(*ptr))) {
977
989
                if (likely(HTTP_IS_SPHT(*ptr)))
978
990
                        EAT_AND_JUMP_OR_RETURN(http_msg_rpver_sp, HTTP_MSG_RPVER_SP);
979
991
                /* so it's a CR/LF, this is invalid */
980
 
                goto http_msg_invalid;
 
992
                state = HTTP_MSG_ERROR;
 
993
                break;
981
994
 
982
995
        http_msg_rpcode:
983
996
        case HTTP_MSG_RPCODE:
1031
1044
        }
1032
1045
 
1033
1046
 http_msg_ood:
1034
 
        /* out of data */
 
1047
        /* out of valid data */
1035
1048
        if (ret_state)
1036
1049
                *ret_state = state;
1037
1050
        if (ret_ptr)
1038
1051
                *ret_ptr = (char *)ptr;
1039
1052
        return NULL;
1040
 
 
1041
 
 http_msg_invalid:
1042
 
        /* invalid message */
1043
 
        if (ret_state)
1044
 
                *ret_state = HTTP_MSG_ERROR;
1045
 
        return NULL;
1046
1053
}
1047
1054
 
1048
1055
 
1069
1076
                               unsigned int state, const char *ptr, const char *end,
1070
1077
                               char **ret_ptr, unsigned int *ret_state)
1071
1078
{
1072
 
        __label__
1073
 
                http_msg_rqmeth,
1074
 
                http_msg_rqmeth_sp,
1075
 
                http_msg_rquri,
1076
 
                http_msg_rquri_sp,
1077
 
                http_msg_rqver,
1078
 
                http_msg_rqline_eol,
1079
 
                http_msg_ood,     /* out of data */
1080
 
                http_msg_invalid;
1081
 
 
1082
1079
        switch (state)  {
1083
1080
        http_msg_rqmeth:
1084
1081
        case HTTP_MSG_RQMETH:
1102
1099
                        msg->sl.rq.v_l = 0;
1103
1100
                        goto http_msg_rqline_eol;
1104
1101
                }
1105
 
                goto http_msg_invalid;
1106
 
                
 
1102
                state = HTTP_MSG_ERROR;
 
1103
                break;
 
1104
 
1107
1105
        http_msg_rqmeth_sp:
1108
1106
        case HTTP_MSG_RQMETH_SP:
1109
1107
                if (likely(!HTTP_IS_LWS(*ptr))) {
1158
1156
                }
1159
1157
 
1160
1158
                /* neither an HTTP_VER token nor a CRLF */
1161
 
                goto http_msg_invalid;
 
1159
                state = HTTP_MSG_ERROR;
 
1160
                break;
1162
1161
 
1163
1162
#ifdef DEBUG_FULL
1164
1163
        default:
1168
1167
        }
1169
1168
 
1170
1169
 http_msg_ood:
1171
 
        /* out of data */
 
1170
        /* out of valid data */
1172
1171
        if (ret_state)
1173
1172
                *ret_state = state;
1174
1173
        if (ret_ptr)
1175
1174
                *ret_ptr = (char *)ptr;
1176
1175
        return NULL;
1177
 
 
1178
 
 http_msg_invalid:
1179
 
        /* invalid message */
1180
 
        if (ret_state)
1181
 
                *ret_state = HTTP_MSG_ERROR;
1182
 
        return NULL;
1183
1176
}
1184
1177
 
1185
1178
 
1193
1186
 */
1194
1187
void http_msg_analyzer(struct buffer *buf, struct http_msg *msg, struct hdr_idx *idx)
1195
1188
{
1196
 
        __label__
1197
 
                http_msg_rqbefore,
1198
 
                http_msg_rqbefore_cr,
1199
 
                http_msg_rqmeth,
1200
 
                http_msg_rqline_end,
1201
 
                http_msg_hdr_first,
1202
 
                http_msg_hdr_name,
1203
 
                http_msg_hdr_l1_sp,
1204
 
                http_msg_hdr_l1_lf,
1205
 
                http_msg_hdr_l1_lws,
1206
 
                http_msg_hdr_val,
1207
 
                http_msg_hdr_l2_lf,
1208
 
                http_msg_hdr_l2_lws,
1209
 
                http_msg_complete_header,
1210
 
                http_msg_last_lf,
1211
 
                http_msg_ood,     /* out of data */
1212
 
                http_msg_invalid;
1213
 
 
1214
1189
        unsigned int state;       /* updated only when leaving the FSM */
1215
1190
        register char *ptr, *end; /* request pointers, to avoid dereferences */
1216
1191
 
1412
1387
                        EAT_AND_JUMP_OR_RETURN(http_msg_hdr_l1_sp, HTTP_MSG_HDR_L1_SP);
1413
1388
                }
1414
1389
 
1415
 
                goto http_msg_invalid;
 
1390
                if (likely(msg->err_pos < -1) || *ptr == '\n')
 
1391
                        goto http_msg_invalid;
 
1392
 
 
1393
                if (msg->err_pos == -1) /* capture error pointer */
 
1394
                        msg->err_pos = ptr - buf->data; /* >= 0 now */
 
1395
 
 
1396
                /* and we still accept this non-token character */
 
1397
                EAT_AND_JUMP_OR_RETURN(http_msg_hdr_name, HTTP_MSG_HDR_NAME);
1416
1398
 
1417
1399
        http_msg_hdr_l1_sp:
1418
1400
        case HTTP_MSG_HDR_L1_SP:
1530
1512
 http_msg_invalid:
1531
1513
        /* invalid message */
1532
1514
        msg->msg_state = HTTP_MSG_ERROR;
 
1515
        buf->lr = ptr;
1533
1516
        return;
1534
1517
}
1535
1518
 
1536
 
/*
1537
 
 * manages the client FSM and its socket. BTW, it also tries to handle the
1538
 
 * cookie. It returns 1 if a state has changed (and a resync may be needed),
1539
 
 * 0 else.
 
1519
/* This function performs all the processing enabled for the current request.
 
1520
 * It returns 1 if the processing can continue on next analysers, or zero if it
 
1521
 * needs more data, encounters an error, or wants to immediately abort the
 
1522
 * request. It relies on buffers flags, and updates s->req->analysers. Its
 
1523
 * behaviour is rather simple:
 
1524
 *  - all enabled analysers are called in turn from the lower to the higher
 
1525
 *    bit.
 
1526
 *  - the analyser must check for errors and timeouts, and react as expected.
 
1527
 *    It does not have to close anything upon error, the caller will.
 
1528
 *  - if the analyser does not have enough data, it must return 0without calling
 
1529
 *    other ones. It should also probably do a buffer_write_dis() to ensure
 
1530
 *    that unprocessed data will not be forwarded. But that probably depends on
 
1531
 *    the protocol.
 
1532
 *  - if an analyser has enough data, it just has to pass on to the next
 
1533
 *    analyser without using buffer_write_dis() (enabled by default).
 
1534
 *  - if an analyser thinks it has no added value anymore staying here, it must
 
1535
 *    reset its bit from the analysers flags in order not to be called anymore.
 
1536
 *
 
1537
 * In the future, analysers should be able to indicate that they want to be
 
1538
 * called after XXX bytes have been received (or transfered), and the min of
 
1539
 * all's wishes will be used to ring back (unless a special condition occurs).
1540
1540
 */
1541
 
int process_cli(struct session *t)
 
1541
int http_process_request(struct session *s, struct buffer *req)
1542
1542
{
1543
 
        int s = t->srv_state;
1544
 
        int c = t->cli_state;
1545
 
        struct buffer *req = t->req;
1546
 
        struct buffer *rep = t->rep;
1547
 
 
1548
 
        DPRINTF(stderr,"process_cli: c=%s s=%s set(r,w)=%d,%d exp(r,w)=%d.%d,%d.%d\n",
1549
 
                cli_stnames[c], srv_stnames[s],
1550
 
                EV_FD_ISSET(t->cli_fd, DIR_RD), EV_FD_ISSET(t->cli_fd, DIR_WR),
1551
 
                req->rex.tv_sec, req->rex.tv_usec,
1552
 
                rep->wex.tv_sec, rep->wex.tv_usec);
1553
 
 
1554
 
        if (c == CL_STHEADERS) {
1555
 
                /*
1556
 
                 * Now parse the partial (or complete) lines.
1557
 
                 * We will check the request syntax, and also join multi-line
1558
 
                 * headers. An index of all the lines will be elaborated while
1559
 
                 * parsing.
1560
 
                 *
1561
 
                 * For the parsing, we use a 28 states FSM.
1562
 
                 *
1563
 
                 * Here is the information we currently have :
1564
 
                 *   req->data + req->som  = beginning of request
1565
 
                 *   req->data + req->eoh  = end of processed headers / start of current one
1566
 
                 *   req->data + req->eol  = end of current header or line (LF or CRLF)
1567
 
                 *   req->lr = first non-visited byte
1568
 
                 *   req->r  = end of data
1569
 
                 */
1570
 
 
1571
 
                int cur_idx;
1572
 
                struct http_txn *txn = &t->txn;
1573
 
                struct http_msg *msg = &txn->req;
1574
 
                struct proxy *cur_proxy;
1575
 
 
1576
 
                if (likely(req->lr < req->r))
1577
 
                        http_msg_analyzer(req, msg, &txn->hdr_idx);
1578
 
 
1579
 
                /* 1: we might have to print this header in debug mode */
1580
 
                if (unlikely((global.mode & MODE_DEBUG) &&
1581
 
                             (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) &&
1582
 
                             (msg->msg_state == HTTP_MSG_BODY || msg->msg_state == HTTP_MSG_ERROR))) {
1583
 
                        char *eol, *sol;
1584
 
 
1585
 
                        sol = req->data + msg->som;
1586
 
                        eol = sol + msg->sl.rq.l;
1587
 
                        debug_hdr("clireq", t, sol, eol);
1588
 
 
1589
 
                        sol += hdr_idx_first_pos(&txn->hdr_idx);
1590
 
                        cur_idx = hdr_idx_first_idx(&txn->hdr_idx);
1591
 
 
1592
 
                        while (cur_idx) {
1593
 
                                eol = sol + txn->hdr_idx.v[cur_idx].len;
1594
 
                                debug_hdr("clihdr", t, sol, eol);
1595
 
                                sol = eol + txn->hdr_idx.v[cur_idx].cr + 1;
1596
 
                                cur_idx = txn->hdr_idx.v[cur_idx].next;
1597
 
                        }
1598
 
                }
1599
 
 
1600
 
 
1601
 
                /*
1602
 
                 * Now we quickly check if we have found a full valid request.
1603
 
                 * If not so, we check the FD and buffer states before leaving.
1604
 
                 * A full request is indicated by the fact that we have seen
1605
 
                 * the double LF/CRLF, so the state is HTTP_MSG_BODY. Invalid
1606
 
                 * requests are checked first.
1607
 
                 *
1608
 
                 */
1609
 
 
1610
 
                if (unlikely(msg->msg_state != HTTP_MSG_BODY)) {
1611
 
                        /*
1612
 
                         * First, let's catch bad requests.
1613
 
                         */
1614
 
                        if (unlikely(msg->msg_state == HTTP_MSG_ERROR))
1615
 
                                goto return_bad_req;
1616
 
 
1617
 
                        /* 1: Since we are in header mode, if there's no space
1618
 
                         *    left for headers, we won't be able to free more
1619
 
                         *    later, so the session will never terminate. We
1620
 
                         *    must terminate it now.
1621
 
                         */
1622
 
                        if (unlikely(req->l >= req->rlim - req->data)) {
1623
 
                                /* FIXME: check if URI is set and return Status
1624
 
                                 * 414 Request URI too long instead.
1625
 
                                 */
1626
 
                                goto return_bad_req;
1627
 
                        }
1628
 
 
1629
 
                        /* 2: have we encountered a read error or a close ? */
1630
 
                        else if (unlikely(req->flags & (BF_READ_ERROR | BF_READ_NULL))) {
1631
 
                                /* read error, or last read : give up. */
1632
 
                                buffer_shutr(req);
1633
 
                                fd_delete(t->cli_fd);
1634
 
                                t->cli_state = CL_STCLOSE;
1635
 
                                t->fe->failed_req++;
1636
 
                                if (!(t->flags & SN_ERR_MASK))
1637
 
                                        t->flags |= SN_ERR_CLICL;
1638
 
                                if (!(t->flags & SN_FINST_MASK))
1639
 
                                        t->flags |= SN_FINST_R;
1640
 
                                return 1;
1641
 
                        }
1642
 
 
1643
 
                        /* 3: has the read timeout expired ? */
1644
 
                        else if (unlikely(tv_isle(&req->rex, &now) ||
1645
 
                                          tv_isle(&txn->exp, &now))) {
1646
 
                                /* read timeout : give up with an error message. */
1647
 
                                txn->status = 408;
1648
 
                                client_retnclose(t, error_message(t, HTTP_ERR_408));
1649
 
                                t->fe->failed_req++;
1650
 
                                if (!(t->flags & SN_ERR_MASK))
1651
 
                                        t->flags |= SN_ERR_CLITO;
1652
 
                                if (!(t->flags & SN_FINST_MASK))
1653
 
                                        t->flags |= SN_FINST_R;
1654
 
                                return 1;
1655
 
                        }
1656
 
 
1657
 
                        /* 4: do we need to re-enable the read socket ? */
1658
 
                        else if (unlikely(EV_FD_COND_S(t->cli_fd, DIR_RD))) {
1659
 
                                /* fd in DIR_RD was disabled, perhaps because of a previous buffer
1660
 
                                 * full. We cannot loop here since stream_sock_read will disable it only if
1661
 
                                 * req->l == rlim-data
1662
 
                                 */
1663
 
                                if (!tv_add_ifset(&req->rex, &now, &t->fe->timeout.client))
1664
 
                                        tv_eternity(&req->rex);
1665
 
                        }
1666
 
                        return t->cli_state != CL_STHEADERS;
1667
 
                }
1668
 
 
1669
 
 
1670
 
                /****************************************************************
1671
 
                 * More interesting part now : we know that we have a complete  *
1672
 
                 * request which at least looks like HTTP. We have an indicator *
1673
 
                 * of each header's length, so we can parse them quickly.       *
1674
 
                 ****************************************************************/
1675
 
 
1676
 
                /* ensure we keep this pointer to the beginning of the message */
 
1543
        /*
 
1544
         * We will parse the partial (or complete) lines.
 
1545
         * We will check the request syntax, and also join multi-line
 
1546
         * headers. An index of all the lines will be elaborated while
 
1547
         * parsing.
 
1548
         *
 
1549
         * For the parsing, we use a 28 states FSM.
 
1550
         *
 
1551
         * Here is the information we currently have :
 
1552
         *   req->data + msg->som  = beginning of request
 
1553
         *   req->data + req->eoh  = end of processed headers / start of current one
 
1554
         *   req->data + req->eol  = end of current header or line (LF or CRLF)
 
1555
         *   req->lr = first non-visited byte
 
1556
         *   req->r  = end of data
 
1557
         */
 
1558
 
 
1559
        int cur_idx;
 
1560
        struct http_txn *txn = &s->txn;
 
1561
        struct http_msg *msg = &txn->req;
 
1562
        struct proxy *cur_proxy;
 
1563
 
 
1564
        DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
 
1565
                now_ms, __FUNCTION__,
 
1566
                s,
 
1567
                req,
 
1568
                req->rex, req->wex,
 
1569
                req->flags,
 
1570
                req->l,
 
1571
                req->analysers);
 
1572
 
 
1573
        if (likely(req->lr < req->r))
 
1574
                http_msg_analyzer(req, msg, &txn->hdr_idx);
 
1575
 
 
1576
        /* 1: we might have to print this header in debug mode */
 
1577
        if (unlikely((global.mode & MODE_DEBUG) &&
 
1578
                     (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) &&
 
1579
                     (msg->msg_state == HTTP_MSG_BODY || msg->msg_state == HTTP_MSG_ERROR))) {
 
1580
                char *eol, *sol;
 
1581
 
 
1582
                sol = req->data + msg->som;
 
1583
                eol = sol + msg->sl.rq.l;
 
1584
                debug_hdr("clireq", s, sol, eol);
 
1585
 
 
1586
                sol += hdr_idx_first_pos(&txn->hdr_idx);
 
1587
                cur_idx = hdr_idx_first_idx(&txn->hdr_idx);
 
1588
 
 
1589
                while (cur_idx) {
 
1590
                        eol = sol + txn->hdr_idx.v[cur_idx].len;
 
1591
                        debug_hdr("clihdr", s, sol, eol);
 
1592
                        sol = eol + txn->hdr_idx.v[cur_idx].cr + 1;
 
1593
                        cur_idx = txn->hdr_idx.v[cur_idx].next;
 
1594
                }
 
1595
        }
 
1596
 
 
1597
 
 
1598
        /*
 
1599
         * Now we quickly check if we have found a full valid request.
 
1600
         * If not so, we check the FD and buffer states before leaving.
 
1601
         * A full request is indicated by the fact that we have seen
 
1602
         * the double LF/CRLF, so the state is HTTP_MSG_BODY. Invalid
 
1603
         * requests are checked first.
 
1604
         *
 
1605
         */
 
1606
 
 
1607
        if (unlikely(msg->msg_state != HTTP_MSG_BODY)) {
 
1608
                /*
 
1609
                 * First, let's catch bad requests.
 
1610
                 */
 
1611
                if (unlikely(msg->msg_state == HTTP_MSG_ERROR))
 
1612
                        goto return_bad_req;
 
1613
 
 
1614
                /* 1: Since we are in header mode, if there's no space
 
1615
                 *    left for headers, we won't be able to free more
 
1616
                 *    later, so the session will never terminate. We
 
1617
                 *    must terminate it now.
 
1618
                 */
 
1619
                if (unlikely(req->flags & BF_FULL)) {
 
1620
                        /* FIXME: check if URI is set and return Status
 
1621
                         * 414 Request URI too long instead.
 
1622
                         */
 
1623
                        goto return_bad_req;
 
1624
                }
 
1625
 
 
1626
                /* 2: have we encountered a read error ? */
 
1627
                else if (req->flags & BF_READ_ERROR) {
 
1628
                        /* we cannot return any message on error */
 
1629
                        if (msg->err_pos >= 0)
 
1630
                                http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
 
1631
                        msg->msg_state = HTTP_MSG_ERROR;
 
1632
                        req->analysers = 0;
 
1633
                        s->fe->failed_req++;
 
1634
                        if (!(s->flags & SN_ERR_MASK))
 
1635
                                s->flags |= SN_ERR_CLICL;
 
1636
                        if (!(s->flags & SN_FINST_MASK))
 
1637
                                s->flags |= SN_FINST_R;
 
1638
                        return 0;
 
1639
                }
 
1640
 
 
1641
                /* 3: has the read timeout expired ? */
 
1642
                else if (req->flags & BF_READ_TIMEOUT || tick_is_expired(req->analyse_exp, now_ms)) {
 
1643
                        /* read timeout : give up with an error message. */
 
1644
                        if (msg->err_pos >= 0)
 
1645
                                http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
 
1646
                        txn->status = 408;
 
1647
                        stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_408));
 
1648
                        msg->msg_state = HTTP_MSG_ERROR;
 
1649
                        req->analysers = 0;
 
1650
                        s->fe->failed_req++;
 
1651
                        if (!(s->flags & SN_ERR_MASK))
 
1652
                                s->flags |= SN_ERR_CLITO;
 
1653
                        if (!(s->flags & SN_FINST_MASK))
 
1654
                                s->flags |= SN_FINST_R;
 
1655
                        return 0;
 
1656
                }
 
1657
 
 
1658
                /* 4: have we encountered a close ? */
 
1659
                else if (req->flags & BF_SHUTR) {
 
1660
                        if (msg->err_pos >= 0)
 
1661
                                http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
 
1662
                        txn->status = 400;
 
1663
                        stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_400));
 
1664
                        msg->msg_state = HTTP_MSG_ERROR;
 
1665
                        req->analysers = 0;
 
1666
                        s->fe->failed_req++;
 
1667
 
 
1668
                        if (!(s->flags & SN_ERR_MASK))
 
1669
                                s->flags |= SN_ERR_CLICL;
 
1670
                        if (!(s->flags & SN_FINST_MASK))
 
1671
                                s->flags |= SN_FINST_R;
 
1672
                        return 0;
 
1673
                }
 
1674
 
 
1675
                buffer_write_dis(req);
 
1676
                req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
 
1677
 
 
1678
                /* just set the request timeout once at the beginning of the request */
 
1679
                if (!tick_isset(req->analyse_exp))
 
1680
                        req->analyse_exp = tick_add_ifset(now_ms, s->fe->timeout.httpreq);
 
1681
 
 
1682
                /* we're not ready yet */
 
1683
                return 0;
 
1684
        }
 
1685
 
 
1686
 
 
1687
        /****************************************************************
 
1688
         * More interesting part now : we know that we have a complete  *
 
1689
         * request which at least looks like HTTP. We have an indicator *
 
1690
         * of each header's length, so we can parse them quickly.       *
 
1691
         ****************************************************************/
 
1692
 
 
1693
        if (msg->err_pos >= 0)
 
1694
                http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
 
1695
 
 
1696
        req->analysers &= ~AN_REQ_HTTP_HDR;
 
1697
        req->analyse_exp = TICK_ETERNITY;
 
1698
 
 
1699
        /* ensure we keep this pointer to the beginning of the message */
 
1700
        msg->sol = req->data + msg->som;
 
1701
 
 
1702
        /*
 
1703
         * 1: identify the method
 
1704
         */
 
1705
        txn->meth = find_http_meth(&req->data[msg->som], msg->sl.rq.m_l);
 
1706
 
 
1707
        /* we can make use of server redirect on GET and HEAD */
 
1708
        if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
 
1709
                s->flags |= SN_REDIRECTABLE;
 
1710
 
 
1711
        /*
 
1712
         * 2: check if the URI matches the monitor_uri.
 
1713
         * We have to do this for every request which gets in, because
 
1714
         * the monitor-uri is defined by the frontend.
 
1715
         */
 
1716
        if (unlikely((s->fe->monitor_uri_len != 0) &&
 
1717
                     (s->fe->monitor_uri_len == msg->sl.rq.u_l) &&
 
1718
                     !memcmp(&req->data[msg->sl.rq.u],
 
1719
                             s->fe->monitor_uri,
 
1720
                             s->fe->monitor_uri_len))) {
 
1721
                /*
 
1722
                 * We have found the monitor URI
 
1723
                 */
 
1724
                struct acl_cond *cond;
 
1725
                cur_proxy = s->fe;
 
1726
 
 
1727
                s->flags |= SN_MONITOR;
 
1728
 
 
1729
                /* Check if we want to fail this monitor request or not */
 
1730
                list_for_each_entry(cond, &cur_proxy->mon_fail_cond, list) {
 
1731
                        int ret = acl_exec_cond(cond, cur_proxy, s, txn, ACL_DIR_REQ);
 
1732
 
 
1733
                        ret = acl_pass(ret);
 
1734
                        if (cond->pol == ACL_COND_UNLESS)
 
1735
                                ret = !ret;
 
1736
 
 
1737
                        if (ret) {
 
1738
                                /* we fail this request, let's return 503 service unavail */
 
1739
                                txn->status = 503;
 
1740
                                stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_503));
 
1741
                                goto return_prx_cond;
 
1742
                        }
 
1743
                }
 
1744
 
 
1745
                /* nothing to fail, let's reply normaly */
 
1746
                txn->status = 200;
 
1747
                stream_int_retnclose(req->prod, &http_200_chunk);
 
1748
                goto return_prx_cond;
 
1749
        }
 
1750
 
 
1751
        /*
 
1752
         * 3: Maybe we have to copy the original REQURI for the logs ?
 
1753
         * Note: we cannot log anymore if the request has been
 
1754
         * classified as invalid.
 
1755
         */
 
1756
        if (unlikely(s->logs.logwait & LW_REQ)) {
 
1757
                /* we have a complete HTTP request that we must log */
 
1758
                if ((txn->uri = pool_alloc2(pool2_requri)) != NULL) {
 
1759
                        int urilen = msg->sl.rq.l;
 
1760
 
 
1761
                        if (urilen >= REQURI_LEN)
 
1762
                                urilen = REQURI_LEN - 1;
 
1763
                        memcpy(txn->uri, &req->data[msg->som], urilen);
 
1764
                        txn->uri[urilen] = 0;
 
1765
 
 
1766
                        if (!(s->logs.logwait &= ~LW_REQ))
 
1767
                                s->do_log(s);
 
1768
                } else {
 
1769
                        Alert("HTTP logging : out of memory.\n");
 
1770
                }
 
1771
        }
 
1772
 
 
1773
        /* 4. We may have to convert HTTP/0.9 requests to HTTP/1.0 */
 
1774
        if (unlikely(msg->sl.rq.v_l == 0)) {
 
1775
                int delta;
 
1776
                char *cur_end;
1677
1777
                msg->sol = req->data + msg->som;
1678
 
 
1679
 
                /*
1680
 
                 * 1: identify the method
1681
 
                 */
1682
 
                txn->meth = find_http_meth(&req->data[msg->som], msg->sl.rq.m_l);
1683
 
 
1684
 
                /*
1685
 
                 * 2: check if the URI matches the monitor_uri.
1686
 
                 * We have to do this for every request which gets in, because
1687
 
                 * the monitor-uri is defined by the frontend.
1688
 
                 */
1689
 
                if (unlikely((t->fe->monitor_uri_len != 0) &&
1690
 
                             (t->fe->monitor_uri_len == msg->sl.rq.u_l) &&
1691
 
                             !memcmp(&req->data[msg->sl.rq.u],
1692
 
                                     t->fe->monitor_uri,
1693
 
                                     t->fe->monitor_uri_len))) {
1694
 
                        /*
1695
 
                         * We have found the monitor URI
1696
 
                         */
1697
 
                        struct acl_cond *cond;
1698
 
                        cur_proxy = t->fe;
1699
 
 
1700
 
                        t->flags |= SN_MONITOR;
1701
 
 
1702
 
                        /* Check if we want to fail this monitor request or not */
1703
 
                        list_for_each_entry(cond, &cur_proxy->mon_fail_cond, list) {
1704
 
                                int ret = acl_exec_cond(cond, cur_proxy, t, txn, ACL_DIR_REQ);
1705
 
                                if (cond->pol == ACL_COND_UNLESS)
1706
 
                                        ret = !ret;
1707
 
 
1708
 
                                if (ret) {
1709
 
                                        /* we fail this request, let's return 503 service unavail */
1710
 
                                        txn->status = 503;
1711
 
                                        client_retnclose(t, error_message(t, HTTP_ERR_503));
1712
 
                                        goto return_prx_cond;
1713
 
                                }
1714
 
                        }
1715
 
 
1716
 
                        /* nothing to fail, let's reply normaly */
1717
 
                        txn->status = 200;
1718
 
                        client_retnclose(t, &http_200_chunk);
1719
 
                        goto return_prx_cond;
1720
 
                }
1721
 
                        
1722
 
                /*
1723
 
                 * 3: Maybe we have to copy the original REQURI for the logs ?
1724
 
                 * Note: we cannot log anymore if the request has been
1725
 
                 * classified as invalid.
1726
 
                 */
1727
 
                if (unlikely(t->logs.logwait & LW_REQ)) {
1728
 
                        /* we have a complete HTTP request that we must log */
1729
 
                        if ((txn->uri = pool_alloc2(pool2_requri)) != NULL) {
1730
 
                                int urilen = msg->sl.rq.l;
1731
 
 
1732
 
                                if (urilen >= REQURI_LEN)
1733
 
                                        urilen = REQURI_LEN - 1;
1734
 
                                memcpy(txn->uri, &req->data[msg->som], urilen);
1735
 
                                txn->uri[urilen] = 0;
1736
 
 
1737
 
                                if (!(t->logs.logwait &= ~LW_REQ))
1738
 
                                        http_sess_log(t);
1739
 
                        } else {
1740
 
                                Alert("HTTP logging : out of memory.\n");
1741
 
                        }
1742
 
                }
1743
 
 
1744
 
 
1745
 
                /* 4. We may have to convert HTTP/0.9 requests to HTTP/1.0 */
1746
 
                if (unlikely(msg->sl.rq.v_l == 0)) {
1747
 
                        int delta;
1748
 
                        char *cur_end;
1749
 
                        msg->sol = req->data + msg->som;
1750
 
                        cur_end = msg->sol + msg->sl.rq.l;
1751
 
                        delta = 0;
1752
 
 
1753
 
                        if (msg->sl.rq.u_l == 0) {
1754
 
                                /* if no URI was set, add "/" */
1755
 
                                delta = buffer_replace2(req, cur_end, cur_end, " /", 2);
1756
 
                                cur_end += delta;
1757
 
                                msg->eoh += delta;
1758
 
                        }
1759
 
                        /* add HTTP version */
1760
 
                        delta = buffer_replace2(req, cur_end, cur_end, " HTTP/1.0\r\n", 11);
 
1778
                cur_end = msg->sol + msg->sl.rq.l;
 
1779
                delta = 0;
 
1780
 
 
1781
                if (msg->sl.rq.u_l == 0) {
 
1782
                        /* if no URI was set, add "/" */
 
1783
                        delta = buffer_replace2(req, cur_end, cur_end, " /", 2);
 
1784
                        cur_end += delta;
1761
1785
                        msg->eoh += delta;
1762
 
                        cur_end += delta;
1763
 
                        cur_end = (char *)http_parse_reqline(msg, req->data,
1764
 
                                                             HTTP_MSG_RQMETH,
1765
 
                                                             msg->sol, cur_end + 1,
1766
 
                                                             NULL, NULL);
1767
 
                        if (unlikely(!cur_end))
1768
 
                                goto return_bad_req;
1769
 
 
1770
 
                        /* we have a full HTTP/1.0 request now and we know that
1771
 
                         * we have either a CR or an LF at <ptr>.
1772
 
                         */
1773
 
                        hdr_idx_set_start(&txn->hdr_idx, msg->sl.rq.l, *cur_end == '\r');
1774
1786
                }
1775
 
 
1776
 
 
1777
 
                /* 5: we may need to capture headers */
1778
 
                if (unlikely((t->logs.logwait & LW_REQHDR) && t->fe->req_cap))
1779
 
                        capture_headers(req->data + msg->som, &txn->hdr_idx,
1780
 
                                        txn->req.cap, t->fe->req_cap);
1781
 
 
1782
 
                /*
1783
 
                 * 6: we will have to evaluate the filters.
1784
 
                 * As opposed to version 1.2, now they will be evaluated in the
1785
 
                 * filters order and not in the header order. This means that
1786
 
                 * each filter has to be validated among all headers.
1787
 
                 *
1788
 
                 * We can now check whether we want to switch to another
1789
 
                 * backend, in which case we will re-check the backend's
1790
 
                 * filters and various options. In order to support 3-level
1791
 
                 * switching, here's how we should proceed :
1792
 
                 *
1793
 
                 *  a) run be.
1794
 
                 *     if (switch) then switch ->be to the new backend.
1795
 
                 *  b) run be if (be != fe).
1796
 
                 *     There cannot be any switch from there, so ->be cannot be
1797
 
                 *     changed anymore.
1798
 
                 *
1799
 
                 * => filters always apply to ->be, then ->be may change.
1800
 
                 *
1801
 
                 * The response path will be able to apply either ->be, or
1802
 
                 * ->be then ->fe filters in order to match the reverse of
1803
 
                 * the forward sequence.
 
1787
                /* add HTTP version */
 
1788
                delta = buffer_replace2(req, cur_end, cur_end, " HTTP/1.0\r\n", 11);
 
1789
                msg->eoh += delta;
 
1790
                cur_end += delta;
 
1791
                cur_end = (char *)http_parse_reqline(msg, req->data,
 
1792
                                                     HTTP_MSG_RQMETH,
 
1793
                                                     msg->sol, cur_end + 1,
 
1794
                                                     NULL, NULL);
 
1795
                if (unlikely(!cur_end))
 
1796
                        goto return_bad_req;
 
1797
 
 
1798
                /* we have a full HTTP/1.0 request now and we know that
 
1799
                 * we have either a CR or an LF at <ptr>.
1804
1800
                 */
1805
 
 
1806
 
                do {
1807
 
                        struct acl_cond *cond;
1808
 
                        struct proxy *rule_set = t->be;
1809
 
                        cur_proxy = t->be;
1810
 
 
1811
 
                        /* first check whether we have some ACLs set to block this request */
1812
 
                        list_for_each_entry(cond, &cur_proxy->block_cond, list) {
1813
 
                                int ret = acl_exec_cond(cond, cur_proxy, t, txn, ACL_DIR_REQ);
1814
 
                                if (cond->pol == ACL_COND_UNLESS)
1815
 
                                        ret = !ret;
1816
 
 
1817
 
                                if (ret) {
1818
 
                                        txn->status = 403;
1819
 
                                        /* let's log the request time */
1820
 
                                        t->logs.tv_request = now;
1821
 
                                        client_retnclose(t, error_message(t, HTTP_ERR_403));
1822
 
                                        goto return_prx_cond;
 
1801
                hdr_idx_set_start(&txn->hdr_idx, msg->sl.rq.l, *cur_end == '\r');
 
1802
        }
 
1803
 
 
1804
 
 
1805
        /* 5: we may need to capture headers */
 
1806
        if (unlikely((s->logs.logwait & LW_REQHDR) && s->fe->req_cap))
 
1807
                capture_headers(req->data + msg->som, &txn->hdr_idx,
 
1808
                                txn->req.cap, s->fe->req_cap);
 
1809
 
 
1810
        /*
 
1811
         * 6: we will have to evaluate the filters.
 
1812
         * As opposed to version 1.2, now they will be evaluated in the
 
1813
         * filters order and not in the header order. This means that
 
1814
         * each filter has to be validated among all headers.
 
1815
         *
 
1816
         * We can now check whether we want to switch to another
 
1817
         * backend, in which case we will re-check the backend's
 
1818
         * filters and various options. In order to support 3-level
 
1819
         * switching, here's how we should proceed :
 
1820
         *
 
1821
         *  a) run be.
 
1822
         *     if (switch) then switch ->be to the new backend.
 
1823
         *  b) run be if (be != fe).
 
1824
         *     There cannot be any switch from there, so ->be cannot be
 
1825
         *     changed anymore.
 
1826
         *
 
1827
         * => filters always apply to ->be, then ->be may change.
 
1828
         *
 
1829
         * The response path will be able to apply either ->be, or
 
1830
         * ->be then ->fe filters in order to match the reverse of
 
1831
         * the forward sequence.
 
1832
         */
 
1833
 
 
1834
        do {
 
1835
                struct acl_cond *cond;
 
1836
                struct redirect_rule *rule;
 
1837
                struct proxy *rule_set = s->be;
 
1838
                cur_proxy = s->be;
 
1839
 
 
1840
                /* first check whether we have some ACLs set to redirect this request */
 
1841
                list_for_each_entry(rule, &cur_proxy->redirect_rules, list) {
 
1842
                        int ret = acl_exec_cond(rule->cond, cur_proxy, s, txn, ACL_DIR_REQ);
 
1843
 
 
1844
                        ret = acl_pass(ret);
 
1845
                        if (rule->cond->pol == ACL_COND_UNLESS)
 
1846
                                ret = !ret;
 
1847
 
 
1848
                        if (ret) {
 
1849
                                struct chunk rdr = { trash, 0 };
 
1850
                                const char *msg_fmt;
 
1851
 
 
1852
                                /* build redirect message */
 
1853
                                switch(rule->code) {
 
1854
                                case 303:
 
1855
                                        rdr.len = strlen(HTTP_303);
 
1856
                                        msg_fmt = HTTP_303;
 
1857
                                        break;
 
1858
                                case 301:
 
1859
                                        rdr.len = strlen(HTTP_301);
 
1860
                                        msg_fmt = HTTP_301;
 
1861
                                        break;
 
1862
                                case 302:
 
1863
                                default:
 
1864
                                        rdr.len = strlen(HTTP_302);
 
1865
                                        msg_fmt = HTTP_302;
 
1866
                                        break;
1823
1867
                                }
1824
 
                        }
1825
1868
 
1826
 
                        /* try headers filters */
1827
 
                        if (rule_set->req_exp != NULL) {
1828
 
                                if (apply_filters_to_request(t, req, rule_set->req_exp) < 0)
 
1869
                                if (unlikely(rdr.len > sizeof(trash)))
1829
1870
                                        goto return_bad_req;
1830
 
                        }
1831
 
 
1832
 
                        if (!(t->flags & SN_BE_ASSIGNED) && (t->be != cur_proxy)) {
1833
 
                                /* to ensure correct connection accounting on
1834
 
                                 * the backend, we count the connection for the
1835
 
                                 * one managing the queue.
1836
 
                                 */
1837
 
                                t->be->beconn++;
1838
 
                                if (t->be->beconn > t->be->beconn_max)
1839
 
                                        t->be->beconn_max = t->be->beconn;
1840
 
                                t->be->cum_beconn++;
1841
 
                                t->flags |= SN_BE_ASSIGNED;
1842
 
                        }
1843
 
 
1844
 
                        /* has the request been denied ? */
1845
 
                        if (txn->flags & TX_CLDENY) {
1846
 
                                /* no need to go further */
 
1871
                                memcpy(rdr.str, msg_fmt, rdr.len);
 
1872
 
 
1873
                                switch(rule->type) {
 
1874
                                case REDIRECT_TYPE_PREFIX: {
 
1875
                                        const char *path;
 
1876
                                        int pathlen;
 
1877
 
 
1878
                                        path = http_get_path(txn);
 
1879
                                        /* build message using path */
 
1880
                                        if (path) {
 
1881
                                                pathlen = txn->req.sl.rq.u_l + (txn->req.sol+txn->req.sl.rq.u) - path;
 
1882
                                                if (rule->flags & REDIRECT_FLAG_DROP_QS) {
 
1883
                                                        int qs = 0;
 
1884
                                                        while (qs < pathlen) {
 
1885
                                                                if (path[qs] == '?') {
 
1886
                                                                        pathlen = qs;
 
1887
                                                                        break;
 
1888
                                                                }
 
1889
                                                                qs++;
 
1890
                                                        }
 
1891
                                                }
 
1892
                                        } else {
 
1893
                                                path = "/";
 
1894
                                                pathlen = 1;
 
1895
                                        }
 
1896
 
 
1897
                                        if (rdr.len + rule->rdr_len + pathlen > sizeof(trash) - 4)
 
1898
                                                goto return_bad_req;
 
1899
 
 
1900
                                        /* add prefix. Note that if prefix == "/", we don't want to
 
1901
                                         * add anything, otherwise it makes it hard for the user to
 
1902
                                         * configure a self-redirection.
 
1903
                                         */
 
1904
                                        if (rule->rdr_len != 1 || *rule->rdr_str != '/') {
 
1905
                                                memcpy(rdr.str + rdr.len, rule->rdr_str, rule->rdr_len);
 
1906
                                                rdr.len += rule->rdr_len;
 
1907
                                        }
 
1908
 
 
1909
                                        /* add path */
 
1910
                                        memcpy(rdr.str + rdr.len, path, pathlen);
 
1911
                                        rdr.len += pathlen;
 
1912
                                        break;
 
1913
                                }
 
1914
                                case REDIRECT_TYPE_LOCATION:
 
1915
                                default:
 
1916
                                        if (rdr.len + rule->rdr_len > sizeof(trash) - 4)
 
1917
                                                goto return_bad_req;
 
1918
 
 
1919
                                        /* add location */
 
1920
                                        memcpy(rdr.str + rdr.len, rule->rdr_str, rule->rdr_len);
 
1921
                                        rdr.len += rule->rdr_len;
 
1922
                                        break;
 
1923
                                }
 
1924
 
 
1925
                                if (rule->cookie_len) {
 
1926
                                        memcpy(rdr.str + rdr.len, "\r\nSet-Cookie: ", 14);
 
1927
                                        rdr.len += 14;
 
1928
                                        memcpy(rdr.str + rdr.len, rule->cookie_str, rule->cookie_len);
 
1929
                                        rdr.len += rule->cookie_len;
 
1930
                                        memcpy(rdr.str + rdr.len, "\r\n", 2);
 
1931
                                        rdr.len += 2;
 
1932
                                }
 
1933
 
 
1934
                                /* add end of headers */
 
1935
                                memcpy(rdr.str + rdr.len, "\r\n\r\n", 4);
 
1936
                                rdr.len += 4;
 
1937
 
 
1938
                                txn->status = rule->code;
 
1939
                                /* let's log the request time */
 
1940
                                s->logs.tv_request = now;
 
1941
                                stream_int_retnclose(req->prod, &rdr);
 
1942
                                goto return_prx_cond;
 
1943
                        }
 
1944
                }
 
1945
 
 
1946
                /* first check whether we have some ACLs set to block this request */
 
1947
                list_for_each_entry(cond, &cur_proxy->block_cond, list) {
 
1948
                        int ret = acl_exec_cond(cond, cur_proxy, s, txn, ACL_DIR_REQ);
 
1949
 
 
1950
                        ret = acl_pass(ret);
 
1951
                        if (cond->pol == ACL_COND_UNLESS)
 
1952
                                ret = !ret;
 
1953
 
 
1954
                        if (ret) {
1847
1955
                                txn->status = 403;
1848
1956
                                /* let's log the request time */
1849
 
                                t->logs.tv_request = now;
1850
 
                                client_retnclose(t, error_message(t, HTTP_ERR_403));
 
1957
                                s->logs.tv_request = now;
 
1958
                                stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_403));
1851
1959
                                goto return_prx_cond;
1852
1960
                        }
1853
 
 
1854
 
                        /* We might have to check for "Connection:" */
1855
 
                        if (((t->fe->options | t->be->options) & (PR_O_HTTP_CLOSE|PR_O_FORCE_CLO)) &&
1856
 
                            !(t->flags & SN_CONN_CLOSED)) {
1857
 
                                char *cur_ptr, *cur_end, *cur_next;
1858
 
                                int cur_idx, old_idx, delta, val;
1859
 
                                struct hdr_idx_elem *cur_hdr;
1860
 
 
1861
 
                                cur_next = req->data + txn->req.som + hdr_idx_first_pos(&txn->hdr_idx);
1862
 
                                old_idx = 0;
1863
 
 
1864
 
                                while ((cur_idx = txn->hdr_idx.v[old_idx].next)) {
1865
 
                                        cur_hdr  = &txn->hdr_idx.v[cur_idx];
1866
 
                                        cur_ptr  = cur_next;
1867
 
                                        cur_end  = cur_ptr + cur_hdr->len;
1868
 
                                        cur_next = cur_end + cur_hdr->cr + 1;
1869
 
 
1870
 
                                        val = http_header_match2(cur_ptr, cur_end, "Connection", 10);
1871
 
                                        if (val) {
1872
 
                                                /* 3 possibilities :
1873
 
                                                 * - we have already set Connection: close,
1874
 
                                                 *   so we remove this line.
1875
 
                                                 * - we have not yet set Connection: close,
1876
 
                                                 *   but this line indicates close. We leave
1877
 
                                                 *   it untouched and set the flag.
1878
 
                                                 * - we have not yet set Connection: close,
1879
 
                                                 *   and this line indicates non-close. We
1880
 
                                                 *   replace it.
1881
 
                                                 */
1882
 
                                                if (t->flags & SN_CONN_CLOSED) {
1883
 
                                                        delta = buffer_replace2(req, cur_ptr, cur_next, NULL, 0);
1884
 
                                                        txn->req.eoh += delta;
1885
 
                                                        cur_next += delta;
1886
 
                                                        txn->hdr_idx.v[old_idx].next = cur_hdr->next;
1887
 
                                                        txn->hdr_idx.used--;
1888
 
                                                        cur_hdr->len = 0;
1889
 
                                                } else {
1890
 
                                                        if (strncasecmp(cur_ptr + val, "close", 5) != 0) {
1891
 
                                                                delta = buffer_replace2(req, cur_ptr + val, cur_end,
1892
 
                                                                                        "close", 5);
1893
 
                                                                cur_next += delta;
1894
 
                                                                cur_hdr->len += delta;
1895
 
                                                                txn->req.eoh += delta;
1896
 
                                                        }
1897
 
                                                        t->flags |= SN_CONN_CLOSED;
1898
 
                                                }
1899
 
                                        }
1900
 
                                        old_idx = cur_idx;
1901
 
                                }
1902
 
                        }
1903
 
                        /* add request headers from the rule sets in the same order */
1904
 
                        for (cur_idx = 0; cur_idx < rule_set->nb_reqadd; cur_idx++) {
1905
 
                                if (unlikely(http_header_add_tail(req,
1906
 
                                                                  &txn->req,
1907
 
                                                                  &txn->hdr_idx,
1908
 
                                                                  rule_set->req_add[cur_idx])) < 0)
1909
 
                                        goto return_bad_req;
1910
 
                        }
1911
 
 
1912
 
                        /* check if stats URI was requested, and if an auth is needed */
1913
 
                        if (rule_set->uri_auth != NULL &&
1914
 
                            (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)) {
1915
 
                                /* we have to check the URI and auth for this request */
1916
 
                                if (stats_check_uri_auth(t, rule_set))
1917
 
                                        return 1;
1918
 
                        }
1919
 
 
1920
 
                        /* now check whether we have some switching rules for this request */
1921
 
                        if (!(t->flags & SN_BE_ASSIGNED)) {
1922
 
                                struct switching_rule *rule;
1923
 
 
1924
 
                                list_for_each_entry(rule, &cur_proxy->switching_rules, list) {
1925
 
                                        int ret;
1926
 
 
1927
 
                                        ret = acl_exec_cond(rule->cond, cur_proxy, t, txn, ACL_DIR_REQ);
1928
 
                                        if (rule->cond->pol == ACL_COND_UNLESS)
1929
 
                                                ret = !ret;
1930
 
 
1931
 
                                        if (ret) {
1932
 
                                                t->be = rule->be.backend;
1933
 
                                                t->be->beconn++;
1934
 
                                                if (t->be->beconn > t->be->beconn_max)
1935
 
                                                        t->be->beconn_max = t->be->beconn;
1936
 
                                                t->be->cum_beconn++;
1937
 
 
1938
 
                                                /* assign new parameters to the session from the new backend */
1939
 
                                                t->rep->rto = t->req->wto = t->be->timeout.server;
1940
 
                                                t->req->cto = t->be->timeout.connect;
1941
 
                                                t->conn_retries = t->be->conn_retries;
1942
 
                                                t->flags |= SN_BE_ASSIGNED;
1943
 
                                                break;
1944
 
                                        }
1945
 
                                }
1946
 
                        }
1947
 
 
1948
 
                        if (!(t->flags & SN_BE_ASSIGNED) && cur_proxy->defbe.be) {
1949
 
                                /* No backend was set, but there was a default
1950
 
                                 * backend set in the frontend, so we use it and
1951
 
                                 * loop again.
1952
 
                                 */
1953
 
                                t->be = cur_proxy->defbe.be;
1954
 
                                t->be->beconn++;
1955
 
                                if (t->be->beconn > t->be->beconn_max)
1956
 
                                        t->be->beconn_max = t->be->beconn;
1957
 
                                t->be->cum_beconn++;
1958
 
 
1959
 
                                /* assign new parameters to the session from the new backend */
1960
 
                                t->rep->rto = t->req->wto = t->be->timeout.server;
1961
 
                                t->req->cto = t->be->timeout.connect;
1962
 
                                t->conn_retries = t->be->conn_retries;
1963
 
                                t->flags |= SN_BE_ASSIGNED;
1964
 
                        }
1965
 
                } while (t->be != cur_proxy);  /* we loop only if t->be has changed */
1966
 
                
1967
 
 
1968
 
                if (!(t->flags & SN_BE_ASSIGNED)) {
1969
 
                        /* To ensure correct connection accounting on
 
1961
                }
 
1962
 
 
1963
                /* try headers filters */
 
1964
                if (rule_set->req_exp != NULL) {
 
1965
                        if (apply_filters_to_request(s, req, rule_set->req_exp) < 0)
 
1966
                                goto return_bad_req;
 
1967
                }
 
1968
 
 
1969
                if (!(s->flags & SN_BE_ASSIGNED) && (s->be != cur_proxy)) {
 
1970
                        /* to ensure correct connection accounting on
1970
1971
                         * the backend, we count the connection for the
1971
1972
                         * one managing the queue.
1972
1973
                         */
1973
 
                        t->be->beconn++;
1974
 
                        if (t->be->beconn > t->be->beconn_max)
1975
 
                                t->be->beconn_max = t->be->beconn;
1976
 
                        t->be->cum_beconn++;
1977
 
                        t->flags |= SN_BE_ASSIGNED;
1978
 
                }
1979
 
 
1980
 
                /*
1981
 
                 * Right now, we know that we have processed the entire headers
1982
 
                 * and that unwanted requests have been filtered out. We can do
1983
 
                 * whatever we want with the remaining request. Also, now we
1984
 
                 * may have separate values for ->fe, ->be.
1985
 
                 */
1986
 
 
1987
 
                /*
1988
 
                 * If HTTP PROXY is set we simply get remote server address
1989
 
                 * parsing incoming request.
1990
 
                 */
1991
 
                if ((t->be->options & PR_O_HTTP_PROXY) && !(t->flags & SN_ADDR_SET)) {
1992
 
                        url2sa(req->data + msg->sl.rq.u, msg->sl.rq.u_l, &t->srv_addr);
1993
 
                }
1994
 
 
1995
 
                /*
1996
 
                 * 7: the appsession cookie was looked up very early in 1.2,
1997
 
                 * so let's do the same now.
1998
 
                 */
1999
 
 
2000
 
                /* It needs to look into the URI */
2001
 
                if (t->be->appsession_name) {
2002
 
                        get_srv_from_appsession(t, &req->data[msg->som], msg->sl.rq.l);
2003
 
                }
2004
 
 
2005
 
 
2006
 
                /*
2007
 
                 * 8: Now we can work with the cookies.
2008
 
                 * Note that doing so might move headers in the request, but
2009
 
                 * the fields will stay coherent and the URI will not move.
2010
 
                 * This should only be performed in the backend.
2011
 
                 */
2012
 
                if ((t->be->cookie_name || t->be->appsession_name || t->fe->capture_name)
2013
 
                    && !(txn->flags & (TX_CLDENY|TX_CLTARPIT)))
2014
 
                        manage_client_side_cookies(t, req);
2015
 
 
2016
 
 
2017
 
                /*
2018
 
                 * 9: add X-Forwarded-For if either the frontend or the backend
2019
 
                 * asks for it.
2020
 
                 */
2021
 
                if ((t->fe->options | t->be->options) & PR_O_FWDFOR) {
2022
 
                        if (t->cli_addr.ss_family == AF_INET) {
2023
 
                                /* Add an X-Forwarded-For header unless the source IP is
2024
 
                                 * in the 'except' network range.
2025
 
                                 */
2026
 
                                if ((!t->fe->except_mask.s_addr ||
2027
 
                                     (((struct sockaddr_in *)&t->cli_addr)->sin_addr.s_addr & t->fe->except_mask.s_addr)
2028
 
                                     != t->fe->except_net.s_addr) &&
2029
 
                                    (!t->be->except_mask.s_addr ||
2030
 
                                     (((struct sockaddr_in *)&t->cli_addr)->sin_addr.s_addr & t->be->except_mask.s_addr)
2031
 
                                     != t->be->except_net.s_addr)) {
2032
 
                                        int len;
2033
 
                                        unsigned char *pn;
2034
 
                                        pn = (unsigned char *)&((struct sockaddr_in *)&t->cli_addr)->sin_addr;
2035
 
 
2036
 
                                        len = sprintf(trash, "X-Forwarded-For: %d.%d.%d.%d",
2037
 
                                                      pn[0], pn[1], pn[2], pn[3]);
2038
 
 
2039
 
                                        if (unlikely(http_header_add_tail2(req, &txn->req,
2040
 
                                                                           &txn->hdr_idx, trash, len)) < 0)
2041
 
                                                goto return_bad_req;
2042
 
                                }
2043
 
                        }
2044
 
                        else if (t->cli_addr.ss_family == AF_INET6) {
2045
 
                                /* FIXME: for the sake of completeness, we should also support
2046
 
                                 * 'except' here, although it is mostly useless in this case.
2047
 
                                 */
2048
 
                                int len;
2049
 
                                char pn[INET6_ADDRSTRLEN];
2050
 
                                inet_ntop(AF_INET6,
2051
 
                                          (const void *)&((struct sockaddr_in6 *)(&t->cli_addr))->sin6_addr,
2052
 
                                          pn, sizeof(pn));
2053
 
                                len = sprintf(trash, "X-Forwarded-For: %s", pn);
2054
 
                                if (unlikely(http_header_add_tail2(req, &txn->req,
2055
 
                                                                   &txn->hdr_idx, trash, len)) < 0)
2056
 
                                        goto return_bad_req;
2057
 
                        }
2058
 
                }
2059
 
 
2060
 
                /*
2061
 
                 * 10: add "Connection: close" if needed and not yet set.
2062
 
                 * Note that we do not need to add it in case of HTTP/1.0.
2063
 
                 */
2064
 
                if (!(t->flags & SN_CONN_CLOSED) &&
2065
 
                    ((t->fe->options | t->be->options) & (PR_O_HTTP_CLOSE|PR_O_FORCE_CLO))) {
2066
 
                        if ((unlikely(msg->sl.rq.v_l != 8) ||
2067
 
                             unlikely(req->data[msg->som + msg->sl.rq.v + 7] != '0')) &&
2068
 
                            unlikely(http_header_add_tail2(req, &txn->req, &txn->hdr_idx,
2069
 
                                                           "Connection: close", 17)) < 0)
2070
 
                                goto return_bad_req;
2071
 
                        t->flags |= SN_CONN_CLOSED;
2072
 
                }
2073
 
                /* Before we switch to data, was assignment set in manage_client_side_cookie?
2074
 
                 * If not assigned, perhaps we are balancing on url_param, but this is a
2075
 
                 * POST; and the parameters are in the body, maybe scan there to find our server.
2076
 
                 * (unless headers overflowed the buffer?)
2077
 
                 */
2078
 
                if (!(t->flags & (SN_ASSIGNED|SN_DIRECT)) &&
2079
 
                     t->txn.meth == HTTP_METH_POST && t->be->url_param_name != NULL &&
2080
 
                     t->be->url_param_post_limit != 0 && req->l < BUFSIZE &&
2081
 
                     memchr(msg->sol + msg->sl.rq.u, '?', msg->sl.rq.u_l) == NULL) {
2082
 
                        /* are there enough bytes here? total == l || r || rlim ?
2083
 
                         * len is unsigned, but eoh is int,
2084
 
                         * how many bytes of body have we received?
2085
 
                         * eoh is the first empty line of the header
2086
 
                         */
2087
 
                        /* already established CRLF or LF at eoh, move to start of message, find message length in buffer */
2088
 
                        unsigned long len = req->l - (msg->sol[msg->eoh] == '\r' ? msg->eoh + 2 : msg->eoh + 1);
2089
 
 
2090
 
                        /* If we have HTTP/1.1 and Expect: 100-continue, then abort.
2091
 
                         * We can't assume responsibility for the server's decision,
2092
 
                         * on this URI and header set. See rfc2616: 14.20, 8.2.3,
2093
 
                         * We also can't change our mind later, about which server to choose, so round robin.
2094
 
                         */
2095
 
                        if ((likely(msg->sl.rq.v_l == 8) && req->data[msg->som + msg->sl.rq.v + 7] == '1')) {
2096
 
                                struct hdr_ctx ctx;
2097
 
                                ctx.idx = 0;
2098
 
                                /* Expect is allowed in 1.1, look for it */
2099
 
                                http_find_header2("Expect", 6, msg->sol, &txn->hdr_idx, &ctx);
2100
 
                                if (ctx.idx != 0  &&
2101
 
                                    unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val,"100-continue",12)==0))
2102
 
                                        /* We can't reliablly stall and wait for data, because of
2103
 
                                         * .NET clients that don't conform to rfc2616; so, no need for
2104
 
                                         * the next block to check length expectations.
2105
 
                                         * We could send 100 status back to the client, but then we need to
2106
 
                                         * re-write headers, and send the message. And this isn't the right
2107
 
                                         * place for that action.
2108
 
                                         * TODO: support Expect elsewhere and delete this block.
 
1974
                        s->be->beconn++;
 
1975
                        if (s->be->beconn > s->be->beconn_max)
 
1976
                                s->be->beconn_max = s->be->beconn;
 
1977
                        proxy_inc_be_ctr(s->be);
 
1978
                        s->flags |= SN_BE_ASSIGNED;
 
1979
                }
 
1980
 
 
1981
                /* has the request been denied ? */
 
1982
                if (txn->flags & TX_CLDENY) {
 
1983
                        /* no need to go further */
 
1984
                        txn->status = 403;
 
1985
                        /* let's log the request time */
 
1986
                        s->logs.tv_request = now;
 
1987
                        stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_403));
 
1988
                        goto return_prx_cond;
 
1989
                }
 
1990
 
 
1991
                /* We might have to check for "Connection:" */
 
1992
                if (((s->fe->options | s->be->options) & (PR_O_HTTP_CLOSE|PR_O_FORCE_CLO)) &&
 
1993
                    !(s->flags & SN_CONN_CLOSED)) {
 
1994
                        char *cur_ptr, *cur_end, *cur_next;
 
1995
                        int cur_idx, old_idx, delta, val;
 
1996
                        struct hdr_idx_elem *cur_hdr;
 
1997
 
 
1998
                        cur_next = req->data + txn->req.som + hdr_idx_first_pos(&txn->hdr_idx);
 
1999
                        old_idx = 0;
 
2000
 
 
2001
                        while ((cur_idx = txn->hdr_idx.v[old_idx].next)) {
 
2002
                                cur_hdr  = &txn->hdr_idx.v[cur_idx];
 
2003
                                cur_ptr  = cur_next;
 
2004
                                cur_end  = cur_ptr + cur_hdr->len;
 
2005
                                cur_next = cur_end + cur_hdr->cr + 1;
 
2006
 
 
2007
                                val = http_header_match2(cur_ptr, cur_end, "Connection", 10);
 
2008
                                if (val) {
 
2009
                                        /* 3 possibilities :
 
2010
                                         * - we have already set Connection: close,
 
2011
                                         *   so we remove this line.
 
2012
                                         * - we have not yet set Connection: close,
 
2013
                                         *   but this line indicates close. We leave
 
2014
                                         *   it untouched and set the flag.
 
2015
                                         * - we have not yet set Connection: close,
 
2016
                                         *   and this line indicates non-close. We
 
2017
                                         *   replace it.
2109
2018
                                         */
2110
 
                                        goto end_check_maybe_wait_for_body;
2111
 
                        }
2112
 
                        if ( likely(len > t->be->url_param_post_limit) ) {
2113
 
                                /* nothing to do, we got enough */
2114
 
                        } else {
2115
 
                                /* limit implies we are supposed to need this many bytes
2116
 
                                 * to find the parameter. Let's see how many bytes we can wait for.
2117
 
                                 */
2118
 
                                long long hint = len;
2119
 
                                struct hdr_ctx ctx;
2120
 
                                ctx.idx = 0;
2121
 
                                http_find_header2("Transfer-Encoding", 17, msg->sol, &txn->hdr_idx, &ctx);
2122
 
                                if (unlikely(ctx.idx && strncasecmp(ctx.line+ctx.val,"chunked",7)==0)) {
2123
 
                                        t->srv_state = SV_STANALYZE;
2124
 
                                } else {
2125
 
                                        ctx.idx = 0;
2126
 
                                        http_find_header2("Content-Length", 14, msg->sol, &txn->hdr_idx, &ctx);
2127
 
                                        /* now if we have a length, we'll take the hint */
2128
 
                                        if ( ctx.idx ) {
2129
 
                                                /* We have Content-Length */
2130
 
                                                if ( strl2llrc(ctx.line+ctx.val,ctx.vlen, &hint) )
2131
 
                                                        hint = 0;         /* parse failure, untrusted client */
2132
 
                                                else {
2133
 
                                                        if ( hint > 0 )
2134
 
                                                                msg->hdr_content_len = hint;
2135
 
                                                        else
2136
 
                                                                hint = 0; /* bad client, sent negative length */
 
2019
                                        if (s->flags & SN_CONN_CLOSED) {
 
2020
                                                delta = buffer_replace2(req, cur_ptr, cur_next, NULL, 0);
 
2021
                                                txn->req.eoh += delta;
 
2022
                                                cur_next += delta;
 
2023
                                                txn->hdr_idx.v[old_idx].next = cur_hdr->next;
 
2024
                                                txn->hdr_idx.used--;
 
2025
                                                cur_hdr->len = 0;
 
2026
                                        } else {
 
2027
                                                if (strncasecmp(cur_ptr + val, "close", 5) != 0) {
 
2028
                                                        delta = buffer_replace2(req, cur_ptr + val, cur_end,
 
2029
                                                                                "close", 5);
 
2030
                                                        cur_next += delta;
 
2031
                                                        cur_hdr->len += delta;
 
2032
                                                        txn->req.eoh += delta;
2137
2033
                                                }
2138
 
                                        }
2139
 
                                        /* but limited to what we care about, maybe we don't expect any entity data (hint == 0) */
2140
 
                                        if ( t->be->url_param_post_limit < hint )
2141
 
                                                hint = t->be->url_param_post_limit;
2142
 
                                        /* now do we really need to buffer more data? */
2143
 
                                        if ( len < hint )
2144
 
                                                t->srv_state = SV_STANALYZE;
2145
 
                                        /* else... There are no body bytes to wait for */
2146
 
                                }
2147
 
                        }
2148
 
                }
2149
 
        end_check_maybe_wait_for_body:
2150
 
 
2151
 
                /*************************************************************
2152
 
                 * OK, that's finished for the headers. We have done what we *
2153
 
                 * could. Let's switch to the DATA state.                    *
2154
 
                 ************************************************************/
2155
 
 
2156
 
                t->cli_state = CL_STDATA;
2157
 
                req->rlim = req->data + BUFSIZE; /* no more rewrite needed */
2158
 
 
2159
 
                t->logs.tv_request = now;
2160
 
 
2161
 
                if (!tv_isset(&t->fe->timeout.client) ||
2162
 
                    (t->srv_state < SV_STDATA && tv_isset(&t->be->timeout.server))) {
2163
 
                        /* If the client has no timeout, or if the server is not ready yet,
2164
 
                         * and we know for sure that it can expire, then it's cleaner to
2165
 
                         * disable the timeout on the client side so that too low values
2166
 
                         * cannot make the sessions abort too early.
2167
 
                         *
2168
 
                         * FIXME-20050705: the server needs a way to re-enable this time-out
2169
 
                         * when it switches its state, otherwise a client can stay connected
2170
 
                         * indefinitely. This now seems to be OK.
2171
 
                         */
2172
 
                        tv_eternity(&req->rex);
2173
 
                }
2174
 
 
2175
 
                /* When a connection is tarpitted, we use the tarpit timeout,
2176
 
                 * which may be the same as the connect timeout if unspecified.
2177
 
                 * If unset, then set it to zero because we really want it to
2178
 
                 * eventually expire.
2179
 
                 */
2180
 
                if (txn->flags & TX_CLTARPIT) {
2181
 
                        t->req->l = 0;
2182
 
                        /* flush the request so that we can drop the connection early
2183
 
                         * if the client closes first.
2184
 
                         */
2185
 
                        if (!tv_add_ifset(&req->cex, &now, &t->be->timeout.tarpit))
2186
 
                                req->cex = now;
2187
 
                }
2188
 
 
2189
 
                /* OK let's go on with the BODY now */
2190
 
                goto process_data;
2191
 
 
2192
 
        return_bad_req: /* let's centralize all bad requests */
2193
 
                txn->req.msg_state = HTTP_MSG_ERROR;
2194
 
                txn->status = 400;
2195
 
                client_retnclose(t, error_message(t, HTTP_ERR_400));
2196
 
                t->fe->failed_req++;
2197
 
        return_prx_cond:
2198
 
                if (!(t->flags & SN_ERR_MASK))
2199
 
                        t->flags |= SN_ERR_PRXCOND;
2200
 
                if (!(t->flags & SN_FINST_MASK))
2201
 
                        t->flags |= SN_FINST_R;
 
2034
                                                s->flags |= SN_CONN_CLOSED;
 
2035
                                        }
 
2036
                                }
 
2037
                                old_idx = cur_idx;
 
2038
                        }
 
2039
                }
 
2040
                /* add request headers from the rule sets in the same order */
 
2041
                for (cur_idx = 0; cur_idx < rule_set->nb_reqadd; cur_idx++) {
 
2042
                        if (unlikely(http_header_add_tail(req,
 
2043
                                                          &txn->req,
 
2044
                                                          &txn->hdr_idx,
 
2045
                                                          rule_set->req_add[cur_idx])) < 0)
 
2046
                                goto return_bad_req;
 
2047
                }
 
2048
 
 
2049
                /* check if stats URI was requested, and if an auth is needed */
 
2050
                if (rule_set->uri_auth != NULL &&
 
2051
                    (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)) {
 
2052
                        /* we have to check the URI and auth for this request.
 
2053
                         * FIXME!!! that one is rather dangerous, we want to
 
2054
                         * make it follow standard rules (eg: clear req->analysers).
 
2055
                         */
 
2056
                        if (stats_check_uri_auth(s, rule_set)) {
 
2057
                                req->analysers = 0;
 
2058
                                return 0;
 
2059
                        }
 
2060
                }
 
2061
 
 
2062
                /* now check whether we have some switching rules for this request */
 
2063
                if (!(s->flags & SN_BE_ASSIGNED)) {
 
2064
                        struct switching_rule *rule;
 
2065
 
 
2066
                        list_for_each_entry(rule, &cur_proxy->switching_rules, list) {
 
2067
                                int ret;
 
2068
 
 
2069
                                ret = acl_exec_cond(rule->cond, cur_proxy, s, txn, ACL_DIR_REQ);
 
2070
 
 
2071
                                ret = acl_pass(ret);
 
2072
                                if (rule->cond->pol == ACL_COND_UNLESS)
 
2073
                                        ret = !ret;
 
2074
 
 
2075
                                if (ret) {
 
2076
                                        s->be = rule->be.backend;
 
2077
                                        s->be->beconn++;
 
2078
                                        if (s->be->beconn > s->be->beconn_max)
 
2079
                                                s->be->beconn_max = s->be->beconn;
 
2080
                                        proxy_inc_be_ctr(s->be);
 
2081
 
 
2082
                                        /* assign new parameters to the session from the new backend */
 
2083
                                        s->rep->rto = s->req->wto = s->be->timeout.server;
 
2084
                                        s->req->cto = s->be->timeout.connect;
 
2085
                                        s->conn_retries = s->be->conn_retries;
 
2086
                                        if (s->be->options2 & PR_O2_RSPBUG_OK)
 
2087
                                                s->txn.rsp.err_pos = -1; /* let buggy responses pass */
 
2088
                                        s->flags |= SN_BE_ASSIGNED;
 
2089
                                        break;
 
2090
                                }
 
2091
                        }
 
2092
                }
 
2093
 
 
2094
                if (!(s->flags & SN_BE_ASSIGNED) && cur_proxy->defbe.be) {
 
2095
                        /* No backend was set, but there was a default
 
2096
                         * backend set in the frontend, so we use it and
 
2097
                         * loop again.
 
2098
                         */
 
2099
                        s->be = cur_proxy->defbe.be;
 
2100
                        s->be->beconn++;
 
2101
                        if (s->be->beconn > s->be->beconn_max)
 
2102
                                s->be->beconn_max = s->be->beconn;
 
2103
                        proxy_inc_be_ctr(s->be);
 
2104
 
 
2105
                        /* assign new parameters to the session from the new backend */
 
2106
                        s->rep->rto = s->req->wto = s->be->timeout.server;
 
2107
                        s->req->cto = s->be->timeout.connect;
 
2108
                        s->conn_retries = s->be->conn_retries;
 
2109
                        if (s->be->options2 & PR_O2_RSPBUG_OK)
 
2110
                                s->txn.rsp.err_pos = -1; /* let buggy responses pass */
 
2111
                        s->flags |= SN_BE_ASSIGNED;
 
2112
                }
 
2113
        } while (s->be != cur_proxy);  /* we loop only if s->be has changed */
 
2114
 
 
2115
        if (!(s->flags & SN_BE_ASSIGNED)) {
 
2116
                /* To ensure correct connection accounting on
 
2117
                 * the backend, we count the connection for the
 
2118
                 * one managing the queue.
 
2119
                 */
 
2120
                s->be->beconn++;
 
2121
                if (s->be->beconn > s->be->beconn_max)
 
2122
                        s->be->beconn_max = s->be->beconn;
 
2123
                proxy_inc_be_ctr(s->be);
 
2124
                s->flags |= SN_BE_ASSIGNED;
 
2125
        }
 
2126
 
 
2127
        /*
 
2128
         * Right now, we know that we have processed the entire headers
 
2129
         * and that unwanted requests have been filtered out. We can do
 
2130
         * whatever we want with the remaining request. Also, now we
 
2131
         * may have separate values for ->fe, ->be.
 
2132
         */
 
2133
 
 
2134
        /*
 
2135
         * If HTTP PROXY is set we simply get remote server address
 
2136
         * parsing incoming request.
 
2137
         */
 
2138
        if ((s->be->options & PR_O_HTTP_PROXY) && !(s->flags & SN_ADDR_SET)) {
 
2139
                url2sa(req->data + msg->sl.rq.u, msg->sl.rq.u_l, &s->srv_addr);
 
2140
        }
 
2141
 
 
2142
        /*
 
2143
         * 7: the appsession cookie was looked up very early in 1.2,
 
2144
         * so let's do the same now.
 
2145
         */
 
2146
 
 
2147
        /* It needs to look into the URI */
 
2148
        if (s->be->appsession_name) {
 
2149
                get_srv_from_appsession(s, &req->data[msg->som], msg->sl.rq.l);
 
2150
        }
 
2151
 
 
2152
        /*
 
2153
         * 8: Now we can work with the cookies.
 
2154
         * Note that doing so might move headers in the request, but
 
2155
         * the fields will stay coherent and the URI will not move.
 
2156
         * This should only be performed in the backend.
 
2157
         */
 
2158
        if ((s->be->cookie_name || s->be->appsession_name || s->fe->capture_name)
 
2159
            && !(txn->flags & (TX_CLDENY|TX_CLTARPIT)))
 
2160
                manage_client_side_cookies(s, req);
 
2161
 
 
2162
        /*
 
2163
         * 9: add X-Forwarded-For if either the frontend or the backend
 
2164
         * asks for it.
 
2165
         */
 
2166
        if ((s->fe->options | s->be->options) & PR_O_FWDFOR) {
 
2167
                if (s->cli_addr.ss_family == AF_INET) {
 
2168
                        /* Add an X-Forwarded-For header unless the source IP is
 
2169
                         * in the 'except' network range.
 
2170
                         */
 
2171
                        if ((!s->fe->except_mask.s_addr ||
 
2172
                             (((struct sockaddr_in *)&s->cli_addr)->sin_addr.s_addr & s->fe->except_mask.s_addr)
 
2173
                             != s->fe->except_net.s_addr) &&
 
2174
                            (!s->be->except_mask.s_addr ||
 
2175
                             (((struct sockaddr_in *)&s->cli_addr)->sin_addr.s_addr & s->be->except_mask.s_addr)
 
2176
                             != s->be->except_net.s_addr)) {
 
2177
                                int len;
 
2178
                                unsigned char *pn;
 
2179
                                pn = (unsigned char *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr;
 
2180
 
 
2181
                                /* Note: we rely on the backend to get the header name to be used for
 
2182
                                 * x-forwarded-for, because the header is really meant for the backends.
 
2183
                                 * However, if the backend did not specify any option, we have to rely
 
2184
                                 * on the frontend's header name.
 
2185
                                 */
 
2186
                                if (s->be->fwdfor_hdr_len) {
 
2187
                                        len = s->be->fwdfor_hdr_len;
 
2188
                                        memcpy(trash, s->be->fwdfor_hdr_name, len);
 
2189
                                } else {
 
2190
                                        len = s->fe->fwdfor_hdr_len;
 
2191
                                        memcpy(trash, s->fe->fwdfor_hdr_name, len);
 
2192
                                        }
 
2193
                                len += sprintf(trash + len, ": %d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]);
 
2194
 
 
2195
                                if (unlikely(http_header_add_tail2(req, &txn->req,
 
2196
                                                                   &txn->hdr_idx, trash, len)) < 0)
 
2197
                                        goto return_bad_req;
 
2198
                        }
 
2199
                }
 
2200
                else if (s->cli_addr.ss_family == AF_INET6) {
 
2201
                        /* FIXME: for the sake of completeness, we should also support
 
2202
                         * 'except' here, although it is mostly useless in this case.
 
2203
                         */
 
2204
                        int len;
 
2205
                        char pn[INET6_ADDRSTRLEN];
 
2206
                        inet_ntop(AF_INET6,
 
2207
                                  (const void *)&((struct sockaddr_in6 *)(&s->cli_addr))->sin6_addr,
 
2208
                                  pn, sizeof(pn));
 
2209
 
 
2210
                        /* Note: we rely on the backend to get the header name to be used for
 
2211
                         * x-forwarded-for, because the header is really meant for the backends.
 
2212
                         * However, if the backend did not specify any option, we have to rely
 
2213
                         * on the frontend's header name.
 
2214
                         */
 
2215
                        if (s->be->fwdfor_hdr_len) {
 
2216
                                len = s->be->fwdfor_hdr_len;
 
2217
                                memcpy(trash, s->be->fwdfor_hdr_name, len);
 
2218
                        } else {
 
2219
                                len = s->fe->fwdfor_hdr_len;
 
2220
                                memcpy(trash, s->fe->fwdfor_hdr_name, len);
 
2221
                        }
 
2222
                        len += sprintf(trash + len, ": %s", pn);
 
2223
 
 
2224
                        if (unlikely(http_header_add_tail2(req, &txn->req,
 
2225
                                                           &txn->hdr_idx, trash, len)) < 0)
 
2226
                                goto return_bad_req;
 
2227
                }
 
2228
        }
 
2229
 
 
2230
        /*
 
2231
         * 10: add X-Original-To if either the frontend or the backend
 
2232
         * asks for it.
 
2233
         */
 
2234
        if ((s->fe->options | s->be->options) & PR_O_ORGTO) {
 
2235
 
 
2236
                /* FIXME: don't know if IPv6 can handle that case too. */
 
2237
                if (s->cli_addr.ss_family == AF_INET) {
 
2238
                        /* Add an X-Original-To header unless the destination IP is
 
2239
                         * in the 'except' network range.
 
2240
                         */
 
2241
                        if (!(s->flags & SN_FRT_ADDR_SET))
 
2242
                                get_frt_addr(s);
 
2243
 
 
2244
                        if ((!s->fe->except_mask_to.s_addr ||
 
2245
                             (((struct sockaddr_in *)&s->frt_addr)->sin_addr.s_addr & s->fe->except_mask_to.s_addr)
 
2246
                             != s->fe->except_to.s_addr) &&
 
2247
                            (!s->be->except_mask_to.s_addr ||
 
2248
                             (((struct sockaddr_in *)&s->frt_addr)->sin_addr.s_addr & s->be->except_mask_to.s_addr)
 
2249
                             != s->be->except_to.s_addr)) {
 
2250
                                int len;
 
2251
                                unsigned char *pn;
 
2252
                                pn = (unsigned char *)&((struct sockaddr_in *)&s->frt_addr)->sin_addr;
 
2253
 
 
2254
                                /* Note: we rely on the backend to get the header name to be used for
 
2255
                                 * x-original-to, because the header is really meant for the backends.
 
2256
                                 * However, if the backend did not specify any option, we have to rely
 
2257
                                 * on the frontend's header name.
 
2258
                                 */
 
2259
                                if (s->be->orgto_hdr_len) {
 
2260
                                        len = s->be->orgto_hdr_len;
 
2261
                                        memcpy(trash, s->be->orgto_hdr_name, len);
 
2262
                                } else {
 
2263
                                        len = s->fe->orgto_hdr_len;
 
2264
                                        memcpy(trash, s->fe->orgto_hdr_name, len);
 
2265
                                        }
 
2266
                                len += sprintf(trash + len, ": %d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]);
 
2267
 
 
2268
                                if (unlikely(http_header_add_tail2(req, &txn->req,
 
2269
                                                                   &txn->hdr_idx, trash, len)) < 0)
 
2270
                                        goto return_bad_req;
 
2271
                        }
 
2272
                }
 
2273
        }
 
2274
 
 
2275
        /*
 
2276
         * 11: add "Connection: close" if needed and not yet set.
 
2277
         * Note that we do not need to add it in case of HTTP/1.0.
 
2278
         */
 
2279
        if (!(s->flags & SN_CONN_CLOSED) &&
 
2280
            ((s->fe->options | s->be->options) & (PR_O_HTTP_CLOSE|PR_O_FORCE_CLO))) {
 
2281
                if ((unlikely(msg->sl.rq.v_l != 8) ||
 
2282
                     unlikely(req->data[msg->som + msg->sl.rq.v + 7] != '0')) &&
 
2283
                    unlikely(http_header_add_tail2(req, &txn->req, &txn->hdr_idx,
 
2284
                                                   "Connection: close", 17)) < 0)
 
2285
                        goto return_bad_req;
 
2286
                s->flags |= SN_CONN_CLOSED;
 
2287
        }
 
2288
        /* Before we switch to data, was assignment set in manage_client_side_cookie?
 
2289
         * If not assigned, perhaps we are balancing on url_param, but this is a
 
2290
         * POST; and the parameters are in the body, maybe scan there to find our server.
 
2291
         * (unless headers overflowed the buffer?)
 
2292
         */
 
2293
        if (!(s->flags & (SN_ASSIGNED|SN_DIRECT)) &&
 
2294
            s->txn.meth == HTTP_METH_POST && s->be->url_param_name != NULL &&
 
2295
            s->be->url_param_post_limit != 0 && !(req->flags & BF_FULL) &&
 
2296
            memchr(msg->sol + msg->sl.rq.u, '?', msg->sl.rq.u_l) == NULL) {
 
2297
                /* are there enough bytes here? total == l || r || rlim ?
 
2298
                 * len is unsigned, but eoh is int,
 
2299
                 * how many bytes of body have we received?
 
2300
                 * eoh is the first empty line of the header
 
2301
                 */
 
2302
                /* already established CRLF or LF at eoh, move to start of message, find message length in buffer */
 
2303
                unsigned long len = req->l - (msg->sol[msg->eoh] == '\r' ? msg->eoh + 2 : msg->eoh + 1);
 
2304
 
 
2305
                /* If we have HTTP/1.1 and Expect: 100-continue, then abort.
 
2306
                 * We can't assume responsibility for the server's decision,
 
2307
                 * on this URI and header set. See rfc2616: 14.20, 8.2.3,
 
2308
                 * We also can't change our mind later, about which server to choose, so round robin.
 
2309
                 */
 
2310
                if ((likely(msg->sl.rq.v_l == 8) && req->data[msg->som + msg->sl.rq.v + 7] == '1')) {
 
2311
                        struct hdr_ctx ctx;
 
2312
                        ctx.idx = 0;
 
2313
                        /* Expect is allowed in 1.1, look for it */
 
2314
                        http_find_header2("Expect", 6, msg->sol, &txn->hdr_idx, &ctx);
 
2315
                        if (ctx.idx != 0  &&
 
2316
                            unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val, "100-continue", 12) == 0))
 
2317
                                /* We can't reliablly stall and wait for data, because of
 
2318
                                 * .NET clients that don't conform to rfc2616; so, no need for
 
2319
                                 * the next block to check length expectations.
 
2320
                                 * We could send 100 status back to the client, but then we need to
 
2321
                                 * re-write headers, and send the message. And this isn't the right
 
2322
                                 * place for that action.
 
2323
                                 * TODO: support Expect elsewhere and delete this block.
 
2324
                                 */
 
2325
                                goto end_check_maybe_wait_for_body;
 
2326
                }
 
2327
 
 
2328
                if (likely(len > s->be->url_param_post_limit)) {
 
2329
                        /* nothing to do, we got enough */
 
2330
                } else {
 
2331
                        /* limit implies we are supposed to need this many bytes
 
2332
                         * to find the parameter. Let's see how many bytes we can wait for.
 
2333
                         */
 
2334
                        long long hint = len;
 
2335
                        struct hdr_ctx ctx;
 
2336
                        ctx.idx = 0;
 
2337
                        http_find_header2("Transfer-Encoding", 17, msg->sol, &txn->hdr_idx, &ctx);
 
2338
                        if (ctx.idx && ctx.vlen >= 7 && strncasecmp(ctx.line+ctx.val, "chunked", 7) == 0) {
 
2339
                                buffer_write_dis(req);
 
2340
                                req->analysers |= AN_REQ_HTTP_BODY;
 
2341
                        }
 
2342
                        else {
 
2343
                                ctx.idx = 0;
 
2344
                                http_find_header2("Content-Length", 14, msg->sol, &txn->hdr_idx, &ctx);
 
2345
                                /* now if we have a length, we'll take the hint */
 
2346
                                if (ctx.idx) {
 
2347
                                        /* We have Content-Length */
 
2348
                                        if (strl2llrc(ctx.line+ctx.val,ctx.vlen, &hint))
 
2349
                                                hint = 0;         /* parse failure, untrusted client */
 
2350
                                        else {
 
2351
                                                if (hint > 0)
 
2352
                                                        msg->hdr_content_len = hint;
 
2353
                                                else
 
2354
                                                        hint = 0; /* bad client, sent negative length */
 
2355
                                        }
 
2356
                                }
 
2357
                                /* but limited to what we care about, maybe we don't expect any entity data (hint == 0) */
 
2358
                                if (s->be->url_param_post_limit < hint)
 
2359
                                        hint = s->be->url_param_post_limit;
 
2360
                                /* now do we really need to buffer more data? */
 
2361
                                if (len < hint) {
 
2362
                                        buffer_write_dis(req);
 
2363
                                        req->analysers |= AN_REQ_HTTP_BODY;
 
2364
                                }
 
2365
                                /* else... There are no body bytes to wait for */
 
2366
                        }
 
2367
                }
 
2368
        }
 
2369
 end_check_maybe_wait_for_body:
 
2370
 
 
2371
        /*************************************************************
 
2372
         * OK, that's finished for the headers. We have done what we *
 
2373
         * could. Let's switch to the DATA state.                    *
 
2374
         ************************************************************/
 
2375
 
 
2376
        buffer_set_rlim(req, BUFSIZE); /* no more rewrite needed */
 
2377
        s->logs.tv_request = now;
 
2378
 
 
2379
        /* When a connection is tarpitted, we use the tarpit timeout,
 
2380
         * which may be the same as the connect timeout if unspecified.
 
2381
         * If unset, then set it to zero because we really want it to
 
2382
         * eventually expire. We build the tarpit as an analyser.
 
2383
         */
 
2384
        if (txn->flags & TX_CLTARPIT) {
 
2385
                buffer_erase(s->req);
 
2386
                /* wipe the request out so that we can drop the connection early
 
2387
                 * if the client closes first.
 
2388
                 */
 
2389
                buffer_write_dis(req);
 
2390
                req->analysers |= AN_REQ_HTTP_TARPIT;
 
2391
                req->analyse_exp = tick_add_ifset(now_ms,  s->be->timeout.tarpit);
 
2392
                if (!req->analyse_exp)
 
2393
                        req->analyse_exp = tick_add(now_ms, 0);
 
2394
        }
 
2395
 
 
2396
        /* OK let's go on with the BODY now */
 
2397
        return 1;
 
2398
 
 
2399
 return_bad_req: /* let's centralize all bad requests */
 
2400
        if (unlikely(msg->msg_state == HTTP_MSG_ERROR) || msg->err_pos >= 0) {
 
2401
                /* we detected a parsing error. We want to archive this request
 
2402
                 * in the dedicated proxy area for later troubleshooting.
 
2403
                 */
 
2404
                http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
 
2405
        }
 
2406
 
 
2407
        txn->req.msg_state = HTTP_MSG_ERROR;
 
2408
        txn->status = 400;
 
2409
        req->analysers = 0;
 
2410
        stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_400));
 
2411
        s->fe->failed_req++;
 
2412
 
 
2413
 return_prx_cond:
 
2414
        if (!(s->flags & SN_ERR_MASK))
 
2415
                s->flags |= SN_ERR_PRXCOND;
 
2416
        if (!(s->flags & SN_FINST_MASK))
 
2417
                s->flags |= SN_FINST_R;
 
2418
        return 0;
 
2419
}
 
2420
 
 
2421
/* This function is an analyser which processes the HTTP tarpit. It always
 
2422
 * returns zero, at the beginning because it prevents any other processing
 
2423
 * from occurring, and at the end because it terminates the request.
 
2424
 */
 
2425
int http_process_tarpit(struct session *s, struct buffer *req)
 
2426
{
 
2427
        struct http_txn *txn = &s->txn;
 
2428
 
 
2429
        /* This connection is being tarpitted. The CLIENT side has
 
2430
         * already set the connect expiration date to the right
 
2431
         * timeout. We just have to check that the client is still
 
2432
         * there and that the timeout has not expired.
 
2433
         */
 
2434
        if ((req->flags & (BF_SHUTR|BF_READ_ERROR)) == 0 &&
 
2435
            !tick_is_expired(req->analyse_exp, now_ms))
 
2436
                return 0;
 
2437
 
 
2438
        /* We will set the queue timer to the time spent, just for
 
2439
         * logging purposes. We fake a 500 server error, so that the
 
2440
         * attacker will not suspect his connection has been tarpitted.
 
2441
         * It will not cause trouble to the logs because we can exclude
 
2442
         * the tarpitted connections by filtering on the 'PT' status flags.
 
2443
         */
 
2444
        s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
 
2445
 
 
2446
        txn->status = 500;
 
2447
        if (req->flags != BF_READ_ERROR)
 
2448
                stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_500));
 
2449
 
 
2450
        req->analysers = 0;
 
2451
        req->analyse_exp = TICK_ETERNITY;
 
2452
 
 
2453
        s->fe->failed_req++;
 
2454
        if (!(s->flags & SN_ERR_MASK))
 
2455
                s->flags |= SN_ERR_PRXCOND;
 
2456
        if (!(s->flags & SN_FINST_MASK))
 
2457
                s->flags |= SN_FINST_T;
 
2458
        return 0;
 
2459
}
 
2460
 
 
2461
/* This function is an analyser which processes the HTTP request body. It looks
 
2462
 * for parameters to be used for the load balancing algorithm (url_param). It
 
2463
 * must only be called after the standard HTTP request processing has occurred,
 
2464
 * because it expects the request to be parsed. It returns zero if it needs to
 
2465
 * read more data, or 1 once it has completed its analysis.
 
2466
 */
 
2467
int http_process_request_body(struct session *s, struct buffer *req)
 
2468
{
 
2469
        struct http_msg *msg = &s->txn.req;
 
2470
        unsigned long body = msg->sol[msg->eoh] == '\r' ? msg->eoh + 2 : msg->eoh + 1;
 
2471
        long long limit = s->be->url_param_post_limit;
 
2472
        struct hdr_ctx ctx;
 
2473
 
 
2474
        /* We have to parse the HTTP request body to find any required data.
 
2475
         * "balance url_param check_post" should have been the only way to get
 
2476
         * into this. We were brought here after HTTP header analysis, so all
 
2477
         * related structures are ready.
 
2478
         */
 
2479
 
 
2480
        ctx.idx = 0;
 
2481
 
 
2482
        /* now if we have a length, we'll take the hint */
 
2483
        http_find_header2("Transfer-Encoding", 17, msg->sol, &s->txn.hdr_idx, &ctx);
 
2484
        if (ctx.idx && ctx.vlen >= 7 && strncasecmp(ctx.line+ctx.val, "chunked", 7) == 0) {
 
2485
                unsigned int chunk = 0;
 
2486
                while (body < req->l && !HTTP_IS_CRLF(msg->sol[body])) {
 
2487
                        char c = msg->sol[body];
 
2488
                        if (ishex(c)) {
 
2489
                                unsigned int hex = toupper(c) - '0';
 
2490
                                if (hex > 9)
 
2491
                                        hex -= 'A' - '9' - 1;
 
2492
                                chunk = (chunk << 4) | hex;
 
2493
                        } else
 
2494
                                break;
 
2495
                        body++;
 
2496
                }
 
2497
                if (body + 2 >= req->l) /* we want CRLF too */
 
2498
                        goto http_body_end; /* end of buffer? data missing! */
 
2499
 
 
2500
                if (memcmp(msg->sol+body, "\r\n", 2) != 0)
 
2501
                        goto http_body_end; /* chunked encoding len ends with CRLF, and we don't have it yet */
 
2502
 
 
2503
                body += 2; // skip CRLF
 
2504
 
 
2505
                /* if we support more then one chunk here, we have to do it again when assigning server
 
2506
                 * 1. how much entity data do we have? new var
 
2507
                 * 2. should save entity_start, entity_cursor, elen & rlen in req; so we don't repeat scanning here
 
2508
                 * 3. test if elen > limit, or set new limit to elen if 0 (end of entity found)
 
2509
                 */
 
2510
 
 
2511
                if (chunk < limit)
 
2512
                        limit = chunk;                  /* only reading one chunk */
 
2513
        } else {
 
2514
                if (msg->hdr_content_len < limit)
 
2515
                        limit = msg->hdr_content_len;
 
2516
        }
 
2517
 
 
2518
 http_body_end:
 
2519
        /* we leave once we know we have nothing left to do. This means that we have
 
2520
         * enough bytes, or that we know we'll not get any more (buffer full, read
 
2521
         * buffer closed).
 
2522
         */
 
2523
        if (req->l - body >= limit ||             /* enough bytes! */
 
2524
            req->flags & (BF_FULL | BF_READ_ERROR | BF_SHUTR | BF_READ_TIMEOUT) ||
 
2525
            tick_is_expired(req->analyse_exp, now_ms)) {
 
2526
                /* The situation will not evolve, so let's give up on the analysis. */
 
2527
                s->logs.tv_request = now;  /* update the request timer to reflect full request */
 
2528
                req->analysers &= ~AN_REQ_HTTP_BODY;
 
2529
                req->analyse_exp = TICK_ETERNITY;
2202
2530
                return 1;
2203
 
 
2204
2531
        }
2205
 
        else if (c == CL_STDATA) {
2206
 
        process_data:
2207
 
                /* FIXME: this error handling is partly buggy because we always report
2208
 
                 * a 'DATA' phase while we don't know if the server was in IDLE, CONN
2209
 
                 * or HEADER phase. BTW, it's not logical to expire the client while
2210
 
                 * we're waiting for the server to connect.
 
2532
        else {
 
2533
                /* Not enough data. We'll re-use the http-request
 
2534
                 * timeout here. Ideally, we should set the timeout
 
2535
                 * relative to the accept() date. We just set the
 
2536
                 * request timeout once at the beginning of the
 
2537
                 * request.
2211
2538
                 */
2212
 
                /* read or write error */
2213
 
                if (rep->flags & BF_WRITE_ERROR || req->flags & BF_READ_ERROR) {
2214
 
                        buffer_shutr(req);
2215
 
                        buffer_shutw(rep);
2216
 
                        fd_delete(t->cli_fd);
2217
 
                        t->cli_state = CL_STCLOSE;
2218
 
                        if (!(t->flags & SN_ERR_MASK))
2219
 
                                t->flags |= SN_ERR_CLICL;
2220
 
                        if (!(t->flags & SN_FINST_MASK)) {
2221
 
                                if (t->pend_pos)
2222
 
                                        t->flags |= SN_FINST_Q;
2223
 
                                else if (s == SV_STCONN)
2224
 
                                        t->flags |= SN_FINST_C;
2225
 
                                else
2226
 
                                        t->flags |= SN_FINST_D;
2227
 
                        }
2228
 
                        return 1;
2229
 
                }
2230
 
                /* last read, or end of server write */
2231
 
                else if (req->flags & BF_READ_NULL || s == SV_STSHUTW || s == SV_STCLOSE) {
2232
 
                        EV_FD_CLR(t->cli_fd, DIR_RD);
2233
 
                        buffer_shutr(req);
2234
 
                        t->cli_state = CL_STSHUTR;
2235
 
                        return 1;
2236
 
                }       
2237
 
                /* last server read and buffer empty */
2238
 
                else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->l == 0)) {
2239
 
                        EV_FD_CLR(t->cli_fd, DIR_WR);
2240
 
                        buffer_shutw(rep);
2241
 
                        shutdown(t->cli_fd, SHUT_WR);
2242
 
                        /* We must ensure that the read part is still alive when switching
2243
 
                         * to shutw */
2244
 
                        EV_FD_SET(t->cli_fd, DIR_RD);
2245
 
                        tv_add_ifset(&req->rex, &now, &t->fe->timeout.client);
2246
 
                        t->cli_state = CL_STSHUTW;
2247
 
                        //fprintf(stderr,"%p:%s(%d), c=%d, s=%d\n", t, __FUNCTION__, __LINE__, t->cli_state, t->cli_state);
2248
 
                        return 1;
2249
 
                }
2250
 
                /* read timeout */
2251
 
                else if (tv_isle(&req->rex, &now)) {
2252
 
                        EV_FD_CLR(t->cli_fd, DIR_RD);
2253
 
                        buffer_shutr(req);
2254
 
                        t->cli_state = CL_STSHUTR;
2255
 
                        if (!(t->flags & SN_ERR_MASK))
2256
 
                                t->flags |= SN_ERR_CLITO;
2257
 
                        if (!(t->flags & SN_FINST_MASK)) {
2258
 
                                if (t->pend_pos)
2259
 
                                        t->flags |= SN_FINST_Q;
2260
 
                                else if (s == SV_STCONN)
2261
 
                                        t->flags |= SN_FINST_C;
2262
 
                                else
2263
 
                                        t->flags |= SN_FINST_D;
2264
 
                        }
2265
 
                        return 1;
2266
 
                }       
2267
 
                /* write timeout */
2268
 
                else if (tv_isle(&rep->wex, &now)) {
2269
 
                        EV_FD_CLR(t->cli_fd, DIR_WR);
2270
 
                        buffer_shutw(rep);
2271
 
                        shutdown(t->cli_fd, SHUT_WR);
2272
 
                        /* We must ensure that the read part is still alive when switching
2273
 
                         * to shutw */
2274
 
                        EV_FD_SET(t->cli_fd, DIR_RD);
2275
 
                        tv_add_ifset(&req->rex, &now, &t->fe->timeout.client);
2276
 
 
2277
 
                        t->cli_state = CL_STSHUTW;
2278
 
                        if (!(t->flags & SN_ERR_MASK))
2279
 
                                t->flags |= SN_ERR_CLITO;
2280
 
                        if (!(t->flags & SN_FINST_MASK)) {
2281
 
                                if (t->pend_pos)
2282
 
                                        t->flags |= SN_FINST_Q;
2283
 
                                else if (s == SV_STCONN)
2284
 
                                        t->flags |= SN_FINST_C;
2285
 
                                else
2286
 
                                        t->flags |= SN_FINST_D;
2287
 
                        }
2288
 
                        return 1;
2289
 
                }
2290
 
 
2291
 
                if (req->l >= req->rlim - req->data) {
2292
 
                        /* no room to read more data */
2293
 
                        if (EV_FD_COND_C(t->cli_fd, DIR_RD)) {
2294
 
                                /* stop reading until we get some space */
2295
 
                                tv_eternity(&req->rex);
2296
 
                        }
2297
 
                } else {
2298
 
                        /* there's still some space in the buffer */
2299
 
                        if (EV_FD_COND_S(t->cli_fd, DIR_RD)) {
2300
 
                                if (!tv_isset(&t->fe->timeout.client) ||
2301
 
                                    (t->srv_state < SV_STDATA && tv_isset(&t->be->timeout.server)))
2302
 
                                        /* If the client has no timeout, or if the server not ready yet, and we
2303
 
                                         * know for sure that it can expire, then it's cleaner to disable the
2304
 
                                         * timeout on the client side so that too low values cannot make the
2305
 
                                         * sessions abort too early.
2306
 
                                         */
2307
 
                                        tv_eternity(&req->rex);
2308
 
                                else
2309
 
                                        tv_add(&req->rex, &now, &t->fe->timeout.client);
2310
 
                        }
2311
 
                }
2312
 
 
2313
 
                if ((rep->l == 0) ||
2314
 
                    ((s < SV_STDATA) /* FIXME: this may be optimized && (rep->w == rep->h)*/)) {
2315
 
                        if (EV_FD_COND_C(t->cli_fd, DIR_WR)) {
2316
 
                                /* stop writing */
2317
 
                                tv_eternity(&rep->wex);
2318
 
                        }
2319
 
                } else {
2320
 
                        /* buffer not empty */
2321
 
                        if (EV_FD_COND_S(t->cli_fd, DIR_WR)) {
2322
 
                                /* restart writing */
2323
 
                                if (tv_add_ifset(&rep->wex, &now, &t->fe->timeout.client)) {
2324
 
                                        /* FIXME: to prevent the client from expiring read timeouts during writes,
2325
 
                                         * we refresh it. */
2326
 
                                        req->rex = rep->wex;
2327
 
                                }
2328
 
                                else
2329
 
                                        tv_eternity(&rep->wex);
2330
 
                        }
2331
 
                }
2332
 
                return 0; /* other cases change nothing */
2333
 
        }
2334
 
        else if (c == CL_STSHUTR) {
2335
 
                if (rep->flags & BF_WRITE_ERROR) {
2336
 
                        buffer_shutw(rep);
2337
 
                        fd_delete(t->cli_fd);
2338
 
                        t->cli_state = CL_STCLOSE;
2339
 
                        if (!(t->flags & SN_ERR_MASK))
2340
 
                                t->flags |= SN_ERR_CLICL;
2341
 
                        if (!(t->flags & SN_FINST_MASK)) {
2342
 
                                if (t->pend_pos)
2343
 
                                        t->flags |= SN_FINST_Q;
2344
 
                                else if (s == SV_STCONN)
2345
 
                                        t->flags |= SN_FINST_C;
2346
 
                                else
2347
 
                                        t->flags |= SN_FINST_D;
2348
 
                        }
2349
 
                        return 1;
2350
 
                }
2351
 
                else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->l == 0)
2352
 
                         && !(t->flags & SN_SELF_GEN)) {
2353
 
                        buffer_shutw(rep);
2354
 
                        fd_delete(t->cli_fd);
2355
 
                        t->cli_state = CL_STCLOSE;
2356
 
                        return 1;
2357
 
                }
2358
 
                else if (tv_isle(&rep->wex, &now)) {
2359
 
                        buffer_shutw(rep);
2360
 
                        fd_delete(t->cli_fd);
2361
 
                        t->cli_state = CL_STCLOSE;
2362
 
                        if (!(t->flags & SN_ERR_MASK))
2363
 
                                t->flags |= SN_ERR_CLITO;
2364
 
                        if (!(t->flags & SN_FINST_MASK)) {
2365
 
                                if (t->pend_pos)
2366
 
                                        t->flags |= SN_FINST_Q;
2367
 
                                else if (s == SV_STCONN)
2368
 
                                        t->flags |= SN_FINST_C;
2369
 
                                else
2370
 
                                        t->flags |= SN_FINST_D;
2371
 
                        }
2372
 
                        return 1;
2373
 
                }
2374
 
 
2375
 
                if (t->flags & SN_SELF_GEN) {
2376
 
                        produce_content(t);
2377
 
                        if (rep->l == 0) {
2378
 
                                buffer_shutw(rep);
2379
 
                                fd_delete(t->cli_fd);
2380
 
                                t->cli_state = CL_STCLOSE;
2381
 
                                return 1;
2382
 
                        }
2383
 
                }
2384
 
 
2385
 
                if ((rep->l == 0)
2386
 
                    || ((s == SV_STHEADERS) /* FIXME: this may be optimized && (rep->w == rep->h)*/)) {
2387
 
                        if (EV_FD_COND_C(t->cli_fd, DIR_WR)) {
2388
 
                                /* stop writing */
2389
 
                                tv_eternity(&rep->wex);
2390
 
                        }
2391
 
                } else {
2392
 
                        /* buffer not empty */
2393
 
                        if (EV_FD_COND_S(t->cli_fd, DIR_WR)) {
2394
 
                                /* restart writing */
2395
 
                                if (!tv_add_ifset(&rep->wex, &now, &t->fe->timeout.client))
2396
 
                                        tv_eternity(&rep->wex);
2397
 
                        }
2398
 
                }
2399
 
                return 0;
2400
 
        }
2401
 
        else if (c == CL_STSHUTW) {
2402
 
                if (req->flags & BF_READ_ERROR) {
2403
 
                        buffer_shutr(req);
2404
 
                        fd_delete(t->cli_fd);
2405
 
                        t->cli_state = CL_STCLOSE;
2406
 
                        if (!(t->flags & SN_ERR_MASK))
2407
 
                                t->flags |= SN_ERR_CLICL;
2408
 
                        if (!(t->flags & SN_FINST_MASK)) {
2409
 
                                if (t->pend_pos)
2410
 
                                        t->flags |= SN_FINST_Q;
2411
 
                                else if (s == SV_STCONN)
2412
 
                                        t->flags |= SN_FINST_C;
2413
 
                                else
2414
 
                                        t->flags |= SN_FINST_D;
2415
 
                        }
2416
 
                        return 1;
2417
 
                }
2418
 
                else if (req->flags & BF_READ_NULL || s == SV_STSHUTW || s == SV_STCLOSE) {
2419
 
                        buffer_shutr(req);
2420
 
                        fd_delete(t->cli_fd);
2421
 
                        t->cli_state = CL_STCLOSE;
2422
 
                        return 1;
2423
 
                }
2424
 
                else if (tv_isle(&req->rex, &now)) {
2425
 
                        buffer_shutr(req);
2426
 
                        fd_delete(t->cli_fd);
2427
 
                        t->cli_state = CL_STCLOSE;
2428
 
                        if (!(t->flags & SN_ERR_MASK))
2429
 
                                t->flags |= SN_ERR_CLITO;
2430
 
                        if (!(t->flags & SN_FINST_MASK)) {
2431
 
                                if (t->pend_pos)
2432
 
                                        t->flags |= SN_FINST_Q;
2433
 
                                else if (s == SV_STCONN)
2434
 
                                        t->flags |= SN_FINST_C;
2435
 
                                else
2436
 
                                        t->flags |= SN_FINST_D;
2437
 
                        }
2438
 
                        return 1;
2439
 
                }
2440
 
                else if (req->l >= req->rlim - req->data) {
2441
 
                        /* no room to read more data */
2442
 
 
2443
 
                        /* FIXME-20050705: is it possible for a client to maintain a session
2444
 
                         * after the timeout by sending more data after it receives a close ?
2445
 
                         */
2446
 
 
2447
 
                        if (EV_FD_COND_C(t->cli_fd, DIR_RD)) {
2448
 
                                /* stop reading until we get some space */
2449
 
                                tv_eternity(&req->rex);
2450
 
                                //fprintf(stderr,"%p:%s(%d), c=%d, s=%d\n", t, __FUNCTION__, __LINE__, t->cli_state, t->cli_state);
2451
 
                        }
2452
 
                } else {
2453
 
                        /* there's still some space in the buffer */
2454
 
                        if (EV_FD_COND_S(t->cli_fd, DIR_RD)) {
2455
 
                                if (!tv_add_ifset(&req->rex, &now, &t->fe->timeout.client))
2456
 
                                        tv_eternity(&req->rex);
2457
 
                                //fprintf(stderr,"%p:%s(%d), c=%d, s=%d\n", t, __FUNCTION__, __LINE__, t->cli_state, t->cli_state);
2458
 
                        }
2459
 
                }
2460
 
                return 0;
2461
 
        }
2462
 
        else { /* CL_STCLOSE: nothing to do */
2463
 
                if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
2464
 
                        int len;
2465
 
                        len = sprintf(trash, "%08x:%s.clicls[%04x:%04x]\n", t->uniq_id, t->be->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
2466
 
                        write(1, trash, len);
2467
 
                }
2468
 
                return 0;
2469
 
        }
2470
 
        return 0;
 
2539
                buffer_write_dis(req);
 
2540
                if (!tick_isset(req->analyse_exp))
 
2541
                        req->analyse_exp = tick_add_ifset(now_ms, s->fe->timeout.httpreq);
 
2542
                return 0;
 
2543
        }
2471
2544
}
2472
2545
 
2473
 
 
2474
 
/*
2475
 
 * manages the server FSM and its socket. It returns 1 if a state has changed
2476
 
 * (and a resync may be needed), 0 else.
 
2546
/* This function performs all the processing enabled for the current response.
 
2547
 * It normally returns zero, but may return 1 if it absolutely needs to be
 
2548
 * called again after other functions. It relies on buffers flags, and updates
 
2549
 * t->rep->analysers. It might make sense to explode it into several other
 
2550
 * functions. It works like process_request (see indications above).
2477
2551
 */
2478
 
int process_srv(struct session *t)
 
2552
int process_response(struct session *t)
2479
2553
{
2480
 
        int s = t->srv_state;
2481
 
        int c = t->cli_state;
2482
2554
        struct http_txn *txn = &t->txn;
2483
2555
        struct buffer *req = t->req;
2484
2556
        struct buffer *rep = t->rep;
2485
 
        int conn_err;
2486
 
 
2487
 
#ifdef DEBUG_FULL
2488
 
        fprintf(stderr,"process_srv: c=%s, s=%s\n", cli_stnames[c], srv_stnames[s]);
2489
 
#endif
2490
 
 
2491
 
#if 0
2492
 
        fprintf(stderr,"%s:%d  fe->clito=%d.%d, fe->conto=%d.%d, fe->srvto=%d.%d\n",
2493
 
                __FUNCTION__, __LINE__,
2494
 
                t->fe->timeout.client.tv_sec, t->fe->timeout.client.tv_usec, 
2495
 
                t->fe->timeout.connect.tv_sec, t->fe->timeout.connect.tv_usec, 
2496
 
                t->fe->timeout.server.tv_sec, t->fe->timeout.server.tv_usec);
2497
 
        fprintf(stderr,"%s:%d  be->clito=%d.%d, be->conto=%d.%d, be->srvto=%d.%d\n",
2498
 
                __FUNCTION__, __LINE__,
2499
 
                t->be->timeout.client.tv_sec, t->be->timeout.client.tv_usec, 
2500
 
                t->be->timeout.connect.tv_sec, t->be->timeout.connect.tv_usec, 
2501
 
                t->be->timeout.server.tv_sec, t->be->timeout.server.tv_usec);
2502
 
 
2503
 
        fprintf(stderr,"%s:%d  req->cto=%d.%d, req->rto=%d.%d, req->wto=%d.%d\n",
2504
 
                __FUNCTION__, __LINE__,
2505
 
                req->cto.tv_sec, req->cto.tv_usec, 
2506
 
                req->rto.tv_sec, req->rto.tv_usec, 
2507
 
                req->wto.tv_sec, req->wto.tv_usec);
2508
 
 
2509
 
        fprintf(stderr,"%s:%d  rep->cto=%d.%d, rep->rto=%d.%d, rep->wto=%d.%d\n",
2510
 
                __FUNCTION__, __LINE__,
2511
 
                rep->cto.tv_sec, rep->cto.tv_usec, 
2512
 
                rep->rto.tv_sec, rep->rto.tv_usec, 
2513
 
                rep->wto.tv_sec, rep->wto.tv_usec);
2514
 
#endif
2515
 
 
2516
 
        //fprintf(stderr,"process_srv: c=%d, s=%d, cr=%d, cw=%d, sr=%d, sw=%d\n", c, s,
2517
 
        //EV_FD_ISSET(t->cli_fd, DIR_RD), EV_FD_ISSET(t->cli_fd, DIR_WR),
2518
 
        //EV_FD_ISSET(t->srv_fd, DIR_RD), EV_FD_ISSET(t->srv_fd, DIR_WR)
2519
 
        //);
2520
 
        if (s == SV_STIDLE) {
2521
 
                /* NOTE: The client processor may switch to SV_STANALYZE, which switches back SV_STIDLE.
2522
 
                 *       This is logcially after CL_STHEADERS completed, CL_STDATA has started, but
2523
 
                 *       we need to defer server selection until more data arrives, if possible.
2524
 
                 *       This is rare, and only if balancing on parameter hash with values in the entity of a POST
2525
 
                 */
2526
 
                if (c == CL_STHEADERS )
2527
 
                        return 0;       /* stay in idle, waiting for data to reach the client side */
2528
 
                else if (c == CL_STCLOSE || c == CL_STSHUTW ||
2529
 
                         (c == CL_STSHUTR &&
2530
 
                          (t->req->l == 0 || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
2531
 
                        tv_eternity(&req->cex);
2532
 
                        if (t->pend_pos)
2533
 
                                t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now);
2534
 
                        /* note that this must not return any error because it would be able to
2535
 
                         * overwrite the client_retnclose() output.
2536
 
                         */
2537
 
                        if (txn->flags & TX_CLTARPIT)
2538
 
                                srv_close_with_err(t, SN_ERR_CLICL, SN_FINST_T, 0, NULL);
2539
 
                        else
2540
 
                                srv_close_with_err(t, SN_ERR_CLICL, t->pend_pos ? SN_FINST_Q : SN_FINST_C, 0, NULL);
2541
 
 
2542
 
                        return 1;
2543
 
                }
2544
 
                else {
2545
 
                        if (txn->flags & TX_CLTARPIT) {
2546
 
                                /* This connection is being tarpitted. The CLIENT side has
2547
 
                                 * already set the connect expiration date to the right
2548
 
                                 * timeout. We just have to check that it has not expired.
2549
 
                                 */
2550
 
                                if (!tv_isle(&req->cex, &now))
2551
 
                                        return 0;
2552
 
 
2553
 
                                /* We will set the queue timer to the time spent, just for
2554
 
                                 * logging purposes. We fake a 500 server error, so that the
2555
 
                                 * attacker will not suspect his connection has been tarpitted.
2556
 
                                 * It will not cause trouble to the logs because we can exclude
2557
 
                                 * the tarpitted connections by filtering on the 'PT' status flags.
2558
 
                                 */
2559
 
                                tv_eternity(&req->cex);
2560
 
                                t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now);
2561
 
                                srv_close_with_err(t, SN_ERR_PRXCOND, SN_FINST_T,
2562
 
                                                   500, error_message(t, HTTP_ERR_500));
2563
 
                                return 1;
2564
 
                        }
2565
 
 
2566
 
                        /* Right now, we will need to create a connection to the server.
2567
 
                         * We might already have tried, and got a connection pending, in
2568
 
                         * which case we will not do anything till it's pending. It's up
2569
 
                         * to any other session to release it and wake us up again.
2570
 
                         */
2571
 
                        if (t->pend_pos) {
2572
 
                                if (!tv_isle(&req->cex, &now)) {
2573
 
                                        return 0;
2574
 
                                } else {
2575
 
                                        /* we've been waiting too long here */
2576
 
                                        tv_eternity(&req->cex);
2577
 
                                        t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now);
2578
 
                                        srv_close_with_err(t, SN_ERR_SRVTO, SN_FINST_Q,
2579
 
                                                           503, error_message(t, HTTP_ERR_503));
2580
 
                                        if (t->srv)
2581
 
                                                t->srv->failed_conns++;
2582
 
                                        t->be->failed_conns++;
2583
 
                                        return 1;
2584
 
                                }
2585
 
                        }
2586
 
 
2587
 
                        do {
2588
 
                                /* first, get a connection */
2589
 
                                if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
2590
 
                                        t->flags |= SN_REDIRECTABLE;
2591
 
 
2592
 
                                if (srv_redispatch_connect(t))
2593
 
                                        return t->srv_state != SV_STIDLE;
2594
 
 
2595
 
                                if ((t->flags & SN_REDIRECTABLE) && t->srv && t->srv->rdr_len) {
2596
 
                                        /* Server supporting redirection and it is possible.
2597
 
                                         * Invalid requests are reported as such. It concerns all
2598
 
                                         * the largest ones.
2599
 
                                         */
2600
 
                                        struct chunk rdr;
2601
 
                                        char *path;
2602
 
                                        int len;
2603
 
 
2604
 
                                        /* 1: create the response header */
2605
 
                                        rdr.len = strlen(HTTP_302);
2606
 
                                        rdr.str = trash;
2607
 
                                        memcpy(rdr.str, HTTP_302, rdr.len);
2608
 
 
2609
 
                                        /* 2: add the server's prefix */
2610
 
                                        if (rdr.len + t->srv->rdr_len > sizeof(trash))
2611
 
                                                goto cancel_redir;
2612
 
 
2613
 
                                        memcpy(rdr.str + rdr.len, t->srv->rdr_pfx, t->srv->rdr_len);
2614
 
                                        rdr.len += t->srv->rdr_len;
2615
 
 
2616
 
                                        /* 3: add the request URI */
2617
 
                                        path = http_get_path(txn);
2618
 
                                        if (!path)
2619
 
                                                goto cancel_redir;
2620
 
                                        len = txn->req.sl.rq.u_l + (txn->req.sol+txn->req.sl.rq.u) - path;
2621
 
                                        if (rdr.len + len > sizeof(trash) - 4) /* 4 for CRLF-CRLF */
2622
 
                                                goto cancel_redir;
2623
 
 
2624
 
                                        memcpy(rdr.str + rdr.len, path, len);
2625
 
                                        rdr.len += len;
2626
 
                                        memcpy(rdr.str + rdr.len, "\r\n\r\n", 4);
2627
 
                                        rdr.len += 4;
2628
 
 
2629
 
                                        srv_close_with_err(t, SN_ERR_PRXCOND, SN_FINST_C, 302, &rdr);
2630
 
                                        /* FIXME: we should increase a counter of redirects per server and per backend. */
2631
 
                                        if (t->srv)
2632
 
                                                t->srv->cum_sess++;
2633
 
                                        return 1;
2634
 
                                cancel_redir:
2635
 
                                        txn->status = 400;
2636
 
                                        t->fe->failed_req++;
2637
 
                                        srv_close_with_err(t, SN_ERR_PRXCOND, SN_FINST_C,
2638
 
                                                           400, error_message(t, HTTP_ERR_400));
2639
 
                                        return 1;
2640
 
                                }
2641
 
 
2642
 
                                /* try to (re-)connect to the server, and fail if we expire the
2643
 
                                 * number of retries.
2644
 
                                 */
2645
 
                                if (srv_retryable_connect(t)) {
2646
 
                                        t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now);
2647
 
                                        return t->srv_state != SV_STIDLE;
2648
 
                                }
2649
 
                        } while (1);
2650
 
                }
2651
 
        }
2652
 
        else if (s == SV_STCONN) { /* connection in progress */
2653
 
                if (c == CL_STCLOSE || c == CL_STSHUTW ||
2654
 
                    (c == CL_STSHUTR &&
2655
 
                     ((t->req->l == 0 && !(req->flags & BF_WRITE_STATUS)) ||
2656
 
                      t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
2657
 
                        tv_eternity(&req->cex);
2658
 
                        if (!(t->flags & SN_CONN_TAR)) {
2659
 
                                /* if we are in turn-around, we have already closed the FD */
2660
 
                                fd_delete(t->srv_fd);
2661
 
                                if (t->srv) {
2662
 
                                        t->srv->cur_sess--;
2663
 
                                        sess_change_server(t, NULL);
2664
 
                                }
2665
 
                        }
2666
 
 
2667
 
                        /* note that this must not return any error because it would be able to
2668
 
                         * overwrite the client_retnclose() output.
2669
 
                         */
2670
 
                        srv_close_with_err(t, SN_ERR_CLICL, SN_FINST_C, 0, NULL);
2671
 
                        return 1;
2672
 
                }
2673
 
                if (!(req->flags & BF_WRITE_STATUS) && !tv_isle(&req->cex, &now)) {
2674
 
                        //fprintf(stderr,"1: c=%d, s=%d, now=%d.%06d, exp=%d.%06d\n", c, s, now.tv_sec, now.tv_usec, req->cex.tv_sec, req->cex.tv_usec);
2675
 
                        return 0; /* nothing changed */
2676
 
                }
2677
 
                else if (!(req->flags & BF_WRITE_STATUS) || (req->flags & BF_WRITE_ERROR)) {
2678
 
                        /* timeout, asynchronous connect error or first write error */
2679
 
                        //fprintf(stderr,"2: c=%d, s=%d\n", c, s);
2680
 
 
2681
 
                        if (t->flags & SN_CONN_TAR) {
2682
 
                                /* We are doing a turn-around waiting for a new connection attempt. */
2683
 
                                if (!tv_isle(&req->cex, &now))
2684
 
                                        return 0;
2685
 
                                t->flags &= ~SN_CONN_TAR;
2686
 
                        }
2687
 
                        else {
2688
 
                                fd_delete(t->srv_fd);
2689
 
                                if (t->srv)
2690
 
                                        t->srv->cur_sess--;
2691
 
 
2692
 
                                if (!(req->flags & BF_WRITE_STATUS))
2693
 
                                        conn_err = SN_ERR_SRVTO; // it was a connect timeout.
2694
 
                                else
2695
 
                                        conn_err = SN_ERR_SRVCL; // it was an asynchronous connect error.
2696
 
 
2697
 
                                /* ensure that we have enough retries left */
2698
 
                                if (srv_count_retry_down(t, conn_err))
2699
 
                                        return 1;
2700
 
 
2701
 
                                if (req->flags & BF_WRITE_ERROR) {
2702
 
                                        /* we encountered an immediate connection error, and we
2703
 
                                         * will have to retry connecting to the same server, most
2704
 
                                         * likely leading to the same result. To avoid this, we
2705
 
                                         * fake a connection timeout to retry after a turn-around
2706
 
                                         * time of 1 second. We will wait in the previous if block.
2707
 
                                         */
2708
 
                                        t->flags |= SN_CONN_TAR;
2709
 
                                        tv_ms_add(&req->cex, &now, 1000);
2710
 
                                        return 0;
2711
 
                                }
2712
 
                        }
2713
 
 
2714
 
                        if (t->srv && t->conn_retries == 0 && t->be->options & PR_O_REDISP) {
2715
 
                                /* We're on our last chance, and the REDISP option was specified.
2716
 
                                 * We will ignore cookie and force to balance or use the dispatcher.
2717
 
                                 */
2718
 
                                /* let's try to offer this slot to anybody */
2719
 
                                if (may_dequeue_tasks(t->srv, t->be))
2720
 
                                        process_srv_queue(t->srv);
2721
 
 
2722
 
                                /* it's left to the dispatcher to choose a server */
2723
 
                                t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
2724
 
                                t->prev_srv = t->srv;
2725
 
 
2726
 
                                /* first, get a connection */
2727
 
                                if (srv_redispatch_connect(t))
2728
 
                                        return t->srv_state != SV_STCONN;
2729
 
                        } else {
2730
 
                                if (t->srv)
2731
 
                                        t->srv->retries++;
2732
 
                                t->be->retries++;
2733
 
                        }
2734
 
 
2735
 
                        do {
2736
 
                                /* Now we will try to either reconnect to the same server or
2737
 
                                 * connect to another server. If the connection gets queued
2738
 
                                 * because all servers are saturated, then we will go back to
2739
 
                                 * the SV_STIDLE state.
2740
 
                                 */
2741
 
                                if (srv_retryable_connect(t)) {
2742
 
                                        t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now);
2743
 
                                        return t->srv_state != SV_STCONN;
2744
 
                                }
2745
 
 
2746
 
                                /* we need to redispatch the connection to another server */
2747
 
                                if (srv_redispatch_connect(t))
2748
 
                                        return t->srv_state != SV_STCONN;
2749
 
                        } while (1);
2750
 
                }
2751
 
                else { /* no error or write 0 */
2752
 
                        t->logs.t_connect = tv_ms_elapsed(&t->logs.tv_accept, &now);
2753
 
 
2754
 
                        //fprintf(stderr,"3: c=%d, s=%d\n", c, s);
2755
 
                        if (req->l == 0) /* nothing to write */ {
2756
 
                                EV_FD_CLR(t->srv_fd, DIR_WR);
2757
 
                                tv_eternity(&req->wex);
2758
 
                        } else  /* need the right to write */ {
2759
 
                                EV_FD_SET(t->srv_fd, DIR_WR);
2760
 
                                if (tv_add_ifset(&req->wex, &now, &t->be->timeout.server)) {
2761
 
                                        /* FIXME: to prevent the server from expiring read timeouts during writes,
2762
 
                                         * we refresh it. */
2763
 
                                        rep->rex = req->wex;
2764
 
                                }
2765
 
                                else
2766
 
                                        tv_eternity(&req->wex);
2767
 
                        }
2768
 
 
2769
 
                        if (t->be->mode == PR_MODE_TCP) { /* let's allow immediate data connection in this case */
2770
 
                                EV_FD_SET(t->srv_fd, DIR_RD);
2771
 
                                if (!tv_add_ifset(&rep->rex, &now, &t->be->timeout.server))
2772
 
                                        tv_eternity(&rep->rex);
2773
 
                
2774
 
                                t->srv_state = SV_STDATA;
2775
 
                                rep->rlim = rep->data + BUFSIZE; /* no rewrite needed */
2776
 
 
2777
 
                                /* if the user wants to log as soon as possible, without counting
2778
 
                                   bytes from the server, then this is the right moment. */
2779
 
                                if (t->fe->to_log && !(t->logs.logwait & LW_BYTES)) {
2780
 
                                        t->logs.t_close = t->logs.t_connect; /* to get a valid end date */
2781
 
                                        tcp_sess_log(t);
2782
 
                                }
2783
 
#ifdef CONFIG_HAP_TCPSPLICE
2784
 
                                if ((t->fe->options & t->be->options) & PR_O_TCPSPLICE) {
2785
 
                                        /* TCP splicing supported by both FE and BE */
2786
 
                                        tcp_splice_splicefd(t->cli_fd, t->srv_fd, 0);
2787
 
                                }
2788
 
#endif
2789
 
                        }
2790
 
                        else {
2791
 
                                t->srv_state = SV_STHEADERS;
2792
 
                                rep->rlim = rep->data + BUFSIZE - MAXREWRITE; /* rewrite needed */
2793
 
                                t->txn.rsp.msg_state = HTTP_MSG_RPBEFORE;
2794
 
                                /* reset hdr_idx which was already initialized by the request.
2795
 
                                 * right now, the http parser does it.
2796
 
                                 * hdr_idx_init(&t->txn.hdr_idx);
2797
 
                                 */
2798
 
                        }
2799
 
                        tv_eternity(&req->cex);
2800
 
                        return 1;
2801
 
                }
2802
 
        }
2803
 
        else if (s == SV_STHEADERS) { /* receiving server headers */
 
2557
 
 
2558
        DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
 
2559
                now_ms, __FUNCTION__,
 
2560
                t,
 
2561
                rep,
 
2562
                rep->rex, rep->wex,
 
2563
                rep->flags,
 
2564
                rep->l,
 
2565
                rep->analysers);
 
2566
 
 
2567
        if (rep->analysers & AN_RTR_HTTP_HDR) { /* receiving server headers */
2804
2568
                /*
2805
2569
                 * Now parse the partial (or complete) lines.
2806
2570
                 * We will check the response syntax, and also join multi-line
2810
2574
                 * For the parsing, we use a 28 states FSM.
2811
2575
                 *
2812
2576
                 * Here is the information we currently have :
2813
 
                 *   rep->data + req->som  = beginning of response
2814
 
                 *   rep->data + req->eoh  = end of processed headers / start of current one
2815
 
                 *   rep->data + req->eol  = end of current header or line (LF or CRLF)
 
2577
                 *   rep->data + rep->som  = beginning of response
 
2578
                 *   rep->data + rep->eoh  = end of processed headers / start of current one
 
2579
                 *   rep->data + rep->eol  = end of current header or line (LF or CRLF)
2816
2580
                 *   rep->lr = first non-visited byte
2817
2581
                 *   rep->r  = end of data
2818
2582
                 */
2845
2609
                        }
2846
2610
                }
2847
2611
 
2848
 
 
2849
 
                if ((rep->l < rep->rlim - rep->data) && EV_FD_COND_S(t->srv_fd, DIR_RD)) {
2850
 
                        /* fd in DIR_RD was disabled, perhaps because of a previous buffer
2851
 
                         * full. We cannot loop here since stream_sock_read will disable it only if
2852
 
                         * rep->l == rlim-data
2853
 
                         */
2854
 
                        if (!tv_add_ifset(&rep->rex, &now, &t->be->timeout.server))
2855
 
                                tv_eternity(&rep->rex);
2856
 
                }
2857
 
 
2858
 
 
2859
2612
                /*
2860
2613
                 * Now we quickly check if we have found a full valid response.
2861
2614
                 * If not so, we check the FD and buffer states before leaving.
2870
2623
                 */
2871
2624
 
2872
2625
                if (unlikely(msg->msg_state != HTTP_MSG_BODY)) {
2873
 
 
2874
 
                        /* Invalid response, or read error or write error */
2875
 
                        if (unlikely((msg->msg_state == HTTP_MSG_ERROR) ||
2876
 
                                     (req->flags & BF_WRITE_ERROR) ||
2877
 
                                     (rep->flags & BF_READ_ERROR))) {
2878
 
                                buffer_shutr(rep);
2879
 
                                buffer_shutw(req);
2880
 
                                fd_delete(t->srv_fd);
2881
 
                                if (t->srv) {
2882
 
                                        t->srv->cur_sess--;
2883
 
                                        t->srv->failed_resp++;
2884
 
                                        sess_change_server(t, NULL);
2885
 
                                }
2886
 
                                t->be->failed_resp++;
2887
 
                                t->srv_state = SV_STCLOSE;
2888
 
                                txn->status = 502;
2889
 
                                client_return(t, error_message(t, HTTP_ERR_502));
 
2626
                        /* Invalid response */
 
2627
                        if (unlikely(msg->msg_state == HTTP_MSG_ERROR)) {
 
2628
                                /* we detected a parsing error. We want to archive this response
 
2629
                                 * in the dedicated proxy area for later troubleshooting.
 
2630
                                 */
 
2631
                        hdr_response_bad:
 
2632
                                if (msg->msg_state == HTTP_MSG_ERROR || msg->err_pos >= 0)
 
2633
                                        http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
 
2634
 
 
2635
                                buffer_shutr_now(rep);
 
2636
                                buffer_shutw_now(req);
 
2637
                                if (t->srv)
 
2638
                                        t->srv->failed_resp++;
 
2639
                                t->be->failed_resp++;
 
2640
                                rep->analysers = 0;
 
2641
                                txn->status = 502;
 
2642
                                stream_int_return(rep->cons, error_message(t, HTTP_ERR_502));
 
2643
                                if (!(t->flags & SN_ERR_MASK))
 
2644
                                        t->flags |= SN_ERR_PRXCOND;
 
2645
                                if (!(t->flags & SN_FINST_MASK))
 
2646
                                        t->flags |= SN_FINST_H;
 
2647
 
 
2648
                                return 0;
 
2649
                        }
 
2650
                        /* too large response does not fit in buffer. */
 
2651
                        else if (rep->flags & BF_FULL) {
 
2652
                                goto hdr_response_bad;
 
2653
                        }
 
2654
                        /* read error */
 
2655
                        else if (rep->flags & BF_READ_ERROR) {
 
2656
                                if (msg->err_pos >= 0)
 
2657
                                        http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
 
2658
                                buffer_shutr_now(rep);
 
2659
                                buffer_shutw_now(req);
 
2660
                                if (t->srv)
 
2661
                                        t->srv->failed_resp++;
 
2662
                                t->be->failed_resp++;
 
2663
                                rep->analysers = 0;
 
2664
                                txn->status = 502;
 
2665
                                stream_int_return(rep->cons, error_message(t, HTTP_ERR_502));
2890
2666
                                if (!(t->flags & SN_ERR_MASK))
2891
2667
                                        t->flags |= SN_ERR_SRVCL;
2892
2668
                                if (!(t->flags & SN_FINST_MASK))
2893
2669
                                        t->flags |= SN_FINST_H;
2894
 
                                /* We used to have a free connection slot. Since we'll never use it,
2895
 
                                 * we have to inform the server that it may be used by another session.
2896
 
                                 */
2897
 
                                if (t->srv && may_dequeue_tasks(t->srv, t->be))
2898
 
                                        process_srv_queue(t->srv);
2899
 
 
2900
 
                                return 1;
2901
 
                        }
2902
 
 
2903
 
                        /* end of client write or end of server read.
2904
 
                         * since we are in header mode, if there's no space left for headers, we
2905
 
                         * won't be able to free more later, so the session will never terminate.
2906
 
                         */
2907
 
                        else if (unlikely(rep->flags & BF_READ_NULL ||
2908
 
                                          c == CL_STSHUTW || c == CL_STCLOSE ||
2909
 
                                          rep->l >= rep->rlim - rep->data)) {
2910
 
                                EV_FD_CLR(t->srv_fd, DIR_RD);
2911
 
                                buffer_shutr(rep);
2912
 
                                t->srv_state = SV_STSHUTR;
2913
 
                                //fprintf(stderr,"%p:%s(%d), c=%d, s=%d\n", t, __FUNCTION__, __LINE__, t->cli_state, t->cli_state);
2914
 
                                return 1;
2915
 
                        }
2916
 
 
2917
 
                        /* read timeout : return a 504 to the client.
2918
 
                         */
2919
 
                        else if (unlikely(EV_FD_ISSET(t->srv_fd, DIR_RD) &&
2920
 
                                          tv_isle(&rep->rex, &now))) {
2921
 
                                buffer_shutr(rep);
2922
 
                                buffer_shutw(req);
2923
 
                                fd_delete(t->srv_fd);
2924
 
                                if (t->srv) {
2925
 
                                        t->srv->cur_sess--;
 
2670
                                return 0;
 
2671
                        }
 
2672
                        /* read timeout : return a 504 to the client. */
 
2673
                        else if (rep->flags & BF_READ_TIMEOUT) {
 
2674
                                if (msg->err_pos >= 0)
 
2675
                                        http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
 
2676
                                buffer_shutr_now(rep);
 
2677
                                buffer_shutw_now(req);
 
2678
                                if (t->srv)
2926
2679
                                        t->srv->failed_resp++;
2927
 
                                        sess_change_server(t, NULL);
2928
 
                                }
2929
2680
                                t->be->failed_resp++;
2930
 
                                t->srv_state = SV_STCLOSE;
 
2681
                                rep->analysers = 0;
2931
2682
                                txn->status = 504;
2932
 
                                client_return(t, error_message(t, HTTP_ERR_504));
2933
 
                                if (!(t->flags & SN_ERR_MASK))
2934
 
                                        t->flags |= SN_ERR_SRVTO;
2935
 
                                if (!(t->flags & SN_FINST_MASK))
2936
 
                                        t->flags |= SN_FINST_H;
2937
 
                                /* We used to have a free connection slot. Since we'll never use it,
2938
 
                                 * we have to inform the server that it may be used by another session.
2939
 
                                 */
2940
 
                                if (t->srv && may_dequeue_tasks(t->srv, t->be))
2941
 
                                        process_srv_queue(t->srv);
2942
 
                                return 1;
2943
 
                        }
2944
 
 
2945
 
                        /* last client read and buffer empty */
2946
 
                        /* FIXME!!! here, we don't want to switch to SHUTW if the
2947
 
                         * client shuts read too early, because we may still have
2948
 
                         * some work to do on the headers.
2949
 
                         * The side-effect is that if the client completely closes its
2950
 
                         * connection during SV_STHEADER, the connection to the server
2951
 
                         * is kept until a response comes back or the timeout is reached.
2952
 
                         */
2953
 
                        else if (unlikely((/*c == CL_STSHUTR ||*/ c == CL_STCLOSE) &&
2954
 
                                          (req->l == 0))) {
2955
 
                                EV_FD_CLR(t->srv_fd, DIR_WR);
2956
 
                                buffer_shutw(req);
2957
 
 
2958
 
                                /* We must ensure that the read part is still
2959
 
                                 * alive when switching to shutw */
2960
 
                                EV_FD_SET(t->srv_fd, DIR_RD);
2961
 
                                tv_add_ifset(&rep->rex, &now, &t->be->timeout.server);
2962
 
 
2963
 
                                shutdown(t->srv_fd, SHUT_WR);
2964
 
                                t->srv_state = SV_STSHUTW;
2965
 
                                return 1;
2966
 
                        }
2967
 
 
2968
 
                        /* write timeout */
2969
 
                        /* FIXME!!! here, we don't want to switch to SHUTW if the
2970
 
                         * client shuts read too early, because we may still have
2971
 
                         * some work to do on the headers.
2972
 
                         */
2973
 
                        else if (unlikely(EV_FD_ISSET(t->srv_fd, DIR_WR) &&
2974
 
                                          tv_isle(&req->wex, &now))) {
2975
 
                                EV_FD_CLR(t->srv_fd, DIR_WR);
2976
 
                                buffer_shutw(req);
2977
 
                                shutdown(t->srv_fd, SHUT_WR);
2978
 
                                /* We must ensure that the read part is still alive
2979
 
                                 * when switching to shutw */
2980
 
                                EV_FD_SET(t->srv_fd, DIR_RD);
2981
 
                                tv_add_ifset(&rep->rex, &now, &t->be->timeout.server);
2982
 
 
2983
 
                                t->srv_state = SV_STSHUTW;
2984
 
                                if (!(t->flags & SN_ERR_MASK))
2985
 
                                        t->flags |= SN_ERR_SRVTO;
2986
 
                                if (!(t->flags & SN_FINST_MASK))
2987
 
                                        t->flags |= SN_FINST_H;
2988
 
                                return 1;
2989
 
                        }
2990
 
 
2991
 
                        /*
2992
 
                         * And now the non-error cases.
2993
 
                         */
2994
 
 
2995
 
                        /* Data remaining in the request buffer.
2996
 
                         * This happens during the first pass here, and during
2997
 
                         * long posts.
2998
 
                         */
2999
 
                        else if (likely(req->l)) {
3000
 
                                if (EV_FD_COND_S(t->srv_fd, DIR_WR)) {
3001
 
                                        /* restart writing */
3002
 
                                        if (tv_add_ifset(&req->wex, &now, &t->be->timeout.server)) {
3003
 
                                                /* FIXME: to prevent the server from expiring read timeouts during writes,
3004
 
                                                 * we refresh it. */
3005
 
                                                rep->rex = req->wex;
3006
 
                                        }
3007
 
                                        else
3008
 
                                                tv_eternity(&req->wex);
3009
 
                                }
3010
 
                        }
3011
 
 
3012
 
                        /* nothing left in the request buffer */
3013
 
                        else {
3014
 
                                if (EV_FD_COND_C(t->srv_fd, DIR_WR)) {
3015
 
                                        /* stop writing */
3016
 
                                        tv_eternity(&req->wex);
3017
 
                                }
3018
 
                        }
3019
 
 
3020
 
                        return t->srv_state != SV_STHEADERS;
 
2683
                                stream_int_return(rep->cons, error_message(t, HTTP_ERR_504));
 
2684
                                if (!(t->flags & SN_ERR_MASK))
 
2685
                                        t->flags |= SN_ERR_SRVTO;
 
2686
                                if (!(t->flags & SN_FINST_MASK))
 
2687
                                        t->flags |= SN_FINST_H;
 
2688
                                return 0;
 
2689
                        }
 
2690
                        /* close from server */
 
2691
                        else if (rep->flags & BF_SHUTR) {
 
2692
                                if (msg->err_pos >= 0)
 
2693
                                        http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
 
2694
                                buffer_shutw_now(req);
 
2695
                                if (t->srv)
 
2696
                                        t->srv->failed_resp++;
 
2697
                                t->be->failed_resp++;
 
2698
                                rep->analysers = 0;
 
2699
                                txn->status = 502;
 
2700
                                stream_int_return(rep->cons, error_message(t, HTTP_ERR_502));
 
2701
                                if (!(t->flags & SN_ERR_MASK))
 
2702
                                        t->flags |= SN_ERR_SRVCL;
 
2703
                                if (!(t->flags & SN_FINST_MASK))
 
2704
                                        t->flags |= SN_FINST_H;
 
2705
                                return 0;
 
2706
                        }
 
2707
                        /* write error to client (we don't send any message then) */
 
2708
                        else if (rep->flags & BF_WRITE_ERROR) {
 
2709
                                if (msg->err_pos >= 0)
 
2710
                                        http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
 
2711
                                buffer_shutr_now(rep);
 
2712
                                t->be->failed_resp++;
 
2713
                                rep->analysers = 0;
 
2714
                                if (!(t->flags & SN_ERR_MASK))
 
2715
                                        t->flags |= SN_ERR_CLICL;
 
2716
                                if (!(t->flags & SN_FINST_MASK))
 
2717
                                        t->flags |= SN_FINST_H;
 
2718
                                return 0;
 
2719
                        }
 
2720
                        buffer_write_dis(rep);
 
2721
                        return 0;
3021
2722
                }
3022
2723
 
3023
2724
 
3027
2728
                 * of each header's length, so we can parse them quickly.        *
3028
2729
                 ****************************************************************/
3029
2730
 
 
2731
                if (msg->err_pos >= 0)
 
2732
                        http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
 
2733
 
 
2734
                rep->analysers &= ~AN_RTR_HTTP_HDR;
 
2735
 
3030
2736
                /* ensure we keep this pointer to the beginning of the message */
3031
2737
                msg->sol = rep->data + msg->som;
3032
2738
 
3090
2796
                        if (rule_set->rsp_exp != NULL) {
3091
2797
                                if (apply_filters_to_response(t, rep, rule_set->rsp_exp) < 0) {
3092
2798
                                return_bad_resp:
3093
 
                                        if (t->srv) {
3094
 
                                                t->srv->cur_sess--;
 
2799
                                        if (t->srv)
3095
2800
                                                t->srv->failed_resp++;
3096
 
                                                sess_change_server(t, NULL);
3097
 
                                        }
3098
2801
                                        cur_proxy->failed_resp++;
3099
2802
                                return_srv_prx_502:
3100
 
                                        buffer_shutr(rep);
3101
 
                                        buffer_shutw(req);
3102
 
                                        fd_delete(t->srv_fd);
3103
 
                                        t->srv_state = SV_STCLOSE;
 
2803
                                        buffer_shutr_now(rep);
 
2804
                                        buffer_shutw_now(req);
 
2805
                                        rep->analysers = 0;
3104
2806
                                        txn->status = 502;
3105
 
                                        client_return(t, error_message(t, HTTP_ERR_502));
 
2807
                                        stream_int_return(rep->cons, error_message(t, HTTP_ERR_502));
3106
2808
                                        if (!(t->flags & SN_ERR_MASK))
3107
2809
                                                t->flags |= SN_ERR_PRXCOND;
3108
2810
                                        if (!(t->flags & SN_FINST_MASK))
3109
2811
                                                t->flags |= SN_FINST_H;
3110
 
                                        /* We used to have a free connection slot. Since we'll never use it,
3111
 
                                         * we have to inform the server that it may be used by another session.
3112
 
                                         */
3113
 
                                        if (t->srv && may_dequeue_tasks(t->srv, cur_proxy))
3114
 
                                                process_srv_queue(t->srv);
3115
 
                                        return 1;
 
2812
                                        return 0;
3116
2813
                                }
3117
2814
                        }
3118
2815
 
3119
2816
                        /* has the response been denied ? */
3120
2817
                        if (txn->flags & TX_SVDENY) {
3121
 
                                if (t->srv) {
3122
 
                                        t->srv->cur_sess--;
 
2818
                                if (t->srv)
3123
2819
                                        t->srv->failed_secu++;
3124
 
                                        sess_change_server(t, NULL);
3125
 
                                }
3126
2820
                                cur_proxy->denied_resp++;
3127
2821
                                goto return_srv_prx_502;
3128
2822
                        }
3220
2914
                                      t->be->cookie_name,
3221
2915
                                      t->srv->cookie ? t->srv->cookie : "; Expires=Thu, 01-Jan-1970 00:00:01 GMT");
3222
2916
 
 
2917
                        if (t->be->cookie_domain)
 
2918
                                len += sprintf(trash+len, "; domain=%s", t->be->cookie_domain);
 
2919
 
3223
2920
                        if (unlikely(http_header_add_tail2(rep, &txn->rsp, &txn->hdr_idx,
3224
2921
                                                           trash, len)) < 0)
3225
2922
                                goto return_bad_resp;
3254
2951
                         * a set-cookie header. We'll block it as requested by
3255
2952
                         * the 'checkcache' option, and send an alert.
3256
2953
                         */
3257
 
                        if (t->srv) {
3258
 
                                t->srv->cur_sess--;
 
2954
                        if (t->srv)
3259
2955
                                t->srv->failed_secu++;
3260
 
                                sess_change_server(t, NULL);
3261
 
                        }
3262
2956
                        t->be->denied_resp++;
3263
2957
 
3264
2958
                        Alert("Blocking cacheable cookie in response from instance %s, server %s.\n",
3283
2977
                        t->flags |= SN_CONN_CLOSED;
3284
2978
                }
3285
2979
 
3286
 
 
3287
2980
                /*************************************************************
3288
2981
                 * OK, that's finished for the headers. We have done what we *
3289
2982
                 * could. Let's switch to the DATA state.                    *
3290
2983
                 ************************************************************/
3291
2984
 
3292
 
                t->srv_state = SV_STDATA;
3293
 
                rep->rlim = rep->data + BUFSIZE; /* no more rewrite needed */
 
2985
                buffer_set_rlim(rep, BUFSIZE); /* no more rewrite needed */
3294
2986
                t->logs.t_data = tv_ms_elapsed(&t->logs.tv_accept, &now);
3295
2987
 
3296
 
                /* client connection already closed or option 'forceclose' required :
3297
 
                 * we close the server's outgoing connection right now.
3298
 
                 */
3299
 
                if ((req->l == 0) &&
3300
 
                    (c == CL_STSHUTR || c == CL_STCLOSE || t->be->options & PR_O_FORCE_CLO)) {
3301
 
                        EV_FD_CLR(t->srv_fd, DIR_WR);
3302
 
                        buffer_shutw(req);
3303
 
 
3304
 
                        /* We must ensure that the read part is still alive when switching
3305
 
                         * to shutw */
3306
 
                        EV_FD_SET(t->srv_fd, DIR_RD);
3307
 
                        tv_add_ifset(&rep->rex, &now, &t->be->timeout.server);
3308
 
 
3309
 
                        shutdown(t->srv_fd, SHUT_WR);
3310
 
                        t->srv_state = SV_STSHUTW;
3311
 
                }
3312
 
 
3313
2988
#ifdef CONFIG_HAP_TCPSPLICE
3314
2989
                if ((t->fe->options & t->be->options) & PR_O_TCPSPLICE) {
3315
2990
                        /* TCP splicing supported by both FE and BE */
3316
 
                        tcp_splice_splicefd(t->cli_fd, t->srv_fd, 0);
 
2991
                        tcp_splice_splicefd(rep->cons->fd, rep->prod->fd, 0);
3317
2992
                }
3318
2993
#endif
3319
2994
                /* if the user wants to log as soon as possible, without counting
3323
2998
                if (t->fe->to_log && !(t->logs.logwait & LW_BYTES)) {
3324
2999
                        t->logs.t_close = t->logs.t_data; /* to get a valid end date */
3325
3000
                        t->logs.bytes_out = txn->rsp.eoh;
3326
 
                        if (t->fe->to_log & LW_REQ)
3327
 
                                http_sess_log(t);
3328
 
                        else
3329
 
                                tcp_sess_log(t);
 
3001
                        t->do_log(t);
3330
3002
                        t->logs.bytes_out = 0;
3331
3003
                }
3332
3004
 
3334
3006
                 * otherwise we would not let the client side wake up.
3335
3007
                 */
3336
3008
 
3337
 
                return 1;
3338
 
        }
3339
 
        else if (s == SV_STDATA) {
3340
 
                /* read or write error */
3341
 
                if (req->flags & BF_WRITE_ERROR || rep->flags & BF_READ_ERROR) {
3342
 
                        buffer_shutr(rep);
3343
 
                        buffer_shutw(req);
3344
 
                        fd_delete(t->srv_fd);
3345
 
                        if (t->srv) {
3346
 
                                t->srv->cur_sess--;
3347
 
                                t->srv->failed_resp++;
3348
 
                                sess_change_server(t, NULL);
3349
 
                        }
3350
 
                        t->be->failed_resp++;
3351
 
                        t->srv_state = SV_STCLOSE;
3352
 
                        if (!(t->flags & SN_ERR_MASK))
3353
 
                                t->flags |= SN_ERR_SRVCL;
3354
 
                        if (!(t->flags & SN_FINST_MASK))
3355
 
                                t->flags |= SN_FINST_D;
3356
 
                        /* We used to have a free connection slot. Since we'll never use it,
3357
 
                         * we have to inform the server that it may be used by another session.
3358
 
                         */
3359
 
                        if (may_dequeue_tasks(t->srv, t->be))
3360
 
                                process_srv_queue(t->srv);
3361
 
 
3362
 
                        return 1;
3363
 
                }
3364
 
                /* last read, or end of client write */
3365
 
                else if (rep->flags & BF_READ_NULL || c == CL_STSHUTW || c == CL_STCLOSE) {
3366
 
                        EV_FD_CLR(t->srv_fd, DIR_RD);
3367
 
                        buffer_shutr(rep);
3368
 
                        t->srv_state = SV_STSHUTR;
3369
 
                        //fprintf(stderr,"%p:%s(%d), c=%d, s=%d\n", t, __FUNCTION__, __LINE__, t->cli_state, t->cli_state);
3370
 
                        return 1;
3371
 
                }
3372
 
                /* end of client read and no more data to send */
3373
 
                else if ((c == CL_STSHUTR || c == CL_STCLOSE) && (req->l == 0)) {
3374
 
                        EV_FD_CLR(t->srv_fd, DIR_WR);
3375
 
                        buffer_shutw(req);
3376
 
                        shutdown(t->srv_fd, SHUT_WR);
3377
 
                        /* We must ensure that the read part is still alive when switching
3378
 
                         * to shutw */
3379
 
                        EV_FD_SET(t->srv_fd, DIR_RD);
3380
 
                        tv_add_ifset(&rep->rex, &now, &t->be->timeout.server);
3381
 
 
3382
 
                        t->srv_state = SV_STSHUTW;
3383
 
                        return 1;
3384
 
                }
3385
 
                /* read timeout */
3386
 
                else if (tv_isle(&rep->rex, &now)) {
3387
 
                        EV_FD_CLR(t->srv_fd, DIR_RD);
3388
 
                        buffer_shutr(rep);
3389
 
                        t->srv_state = SV_STSHUTR;
3390
 
                        if (!(t->flags & SN_ERR_MASK))
3391
 
                                t->flags |= SN_ERR_SRVTO;
3392
 
                        if (!(t->flags & SN_FINST_MASK))
3393
 
                                t->flags |= SN_FINST_D;
3394
 
                        return 1;
3395
 
                }       
3396
 
                /* write timeout */
3397
 
                else if (tv_isle(&req->wex, &now)) {
3398
 
                        EV_FD_CLR(t->srv_fd, DIR_WR);
3399
 
                        buffer_shutw(req);
3400
 
                        shutdown(t->srv_fd, SHUT_WR);
3401
 
                        /* We must ensure that the read part is still alive when switching
3402
 
                         * to shutw */
3403
 
                        EV_FD_SET(t->srv_fd, DIR_RD);
3404
 
                        tv_add_ifset(&rep->rex, &now, &t->be->timeout.server);
3405
 
                        t->srv_state = SV_STSHUTW;
3406
 
                        if (!(t->flags & SN_ERR_MASK))
3407
 
                                t->flags |= SN_ERR_SRVTO;
3408
 
                        if (!(t->flags & SN_FINST_MASK))
3409
 
                                t->flags |= SN_FINST_D;
3410
 
                        return 1;
3411
 
                }
3412
 
 
3413
 
                /* recompute request time-outs */
3414
 
                if (req->l == 0) {
3415
 
                        if (EV_FD_COND_C(t->srv_fd, DIR_WR)) {
3416
 
                                /* stop writing */
3417
 
                                tv_eternity(&req->wex);
3418
 
                        }
3419
 
                }
3420
 
                else { /* buffer not empty, there are still data to be transferred */
3421
 
                        if (EV_FD_COND_S(t->srv_fd, DIR_WR)) {
3422
 
                                /* restart writing */
3423
 
                                if (tv_add_ifset(&req->wex, &now, &t->be->timeout.server)) {
3424
 
                                        /* FIXME: to prevent the server from expiring read timeouts during writes,
3425
 
                                         * we refresh it. */
3426
 
                                        rep->rex = req->wex;
3427
 
                                }
3428
 
                                else
3429
 
                                        tv_eternity(&req->wex);
3430
 
                        }
3431
 
                }
3432
 
 
3433
 
                /* recompute response time-outs */
3434
 
                if (rep->l == BUFSIZE) { /* no room to read more data */
3435
 
                        if (EV_FD_COND_C(t->srv_fd, DIR_RD)) {
3436
 
                                tv_eternity(&rep->rex);
3437
 
                        }
3438
 
                }
3439
 
                else {
3440
 
                        if (EV_FD_COND_S(t->srv_fd, DIR_RD)) {
3441
 
                                if (!tv_add_ifset(&rep->rex, &now, &t->be->timeout.server))
3442
 
                                        tv_eternity(&rep->rex);
3443
 
                        }
3444
 
                }
3445
 
 
3446
 
                return 0; /* other cases change nothing */
3447
 
        }
3448
 
        else if (s == SV_STSHUTR) {
3449
 
                if (req->flags & BF_WRITE_ERROR) {
3450
 
                        //EV_FD_CLR(t->srv_fd, DIR_WR);
3451
 
                        buffer_shutw(req);
3452
 
                        fd_delete(t->srv_fd);
3453
 
                        if (t->srv) {
3454
 
                                t->srv->cur_sess--;
3455
 
                                t->srv->failed_resp++;
3456
 
                                sess_change_server(t, NULL);
3457
 
                        }
3458
 
                        t->be->failed_resp++;
3459
 
                        //close(t->srv_fd);
3460
 
                        t->srv_state = SV_STCLOSE;
3461
 
                        if (!(t->flags & SN_ERR_MASK))
3462
 
                                t->flags |= SN_ERR_SRVCL;
3463
 
                        if (!(t->flags & SN_FINST_MASK))
3464
 
                                t->flags |= SN_FINST_D;
3465
 
                        /* We used to have a free connection slot. Since we'll never use it,
3466
 
                         * we have to inform the server that it may be used by another session.
3467
 
                         */
3468
 
                        if (may_dequeue_tasks(t->srv, t->be))
3469
 
                                process_srv_queue(t->srv);
3470
 
 
3471
 
                        return 1;
3472
 
                }
3473
 
                else if ((c == CL_STSHUTR || c == CL_STCLOSE) && (req->l == 0)) {
3474
 
                        //EV_FD_CLR(t->srv_fd, DIR_WR);
3475
 
                        buffer_shutw(req);
3476
 
                        fd_delete(t->srv_fd);
3477
 
                        if (t->srv) {
3478
 
                                t->srv->cur_sess--;
3479
 
                                sess_change_server(t, NULL);
3480
 
                        }
3481
 
                        //close(t->srv_fd);
3482
 
                        t->srv_state = SV_STCLOSE;
3483
 
                        /* We used to have a free connection slot. Since we'll never use it,
3484
 
                         * we have to inform the server that it may be used by another session.
3485
 
                         */
3486
 
                        if (may_dequeue_tasks(t->srv, t->be))
3487
 
                                process_srv_queue(t->srv);
3488
 
 
3489
 
                        return 1;
3490
 
                }
3491
 
                else if (tv_isle(&req->wex, &now)) {
3492
 
                        //EV_FD_CLR(t->srv_fd, DIR_WR);
3493
 
                        buffer_shutw(req);
3494
 
                        fd_delete(t->srv_fd);
3495
 
                        if (t->srv) {
3496
 
                                t->srv->cur_sess--;
3497
 
                                sess_change_server(t, NULL);
3498
 
                        }
3499
 
                        //close(t->srv_fd);
3500
 
                        t->srv_state = SV_STCLOSE;
3501
 
                        if (!(t->flags & SN_ERR_MASK))
3502
 
                                t->flags |= SN_ERR_SRVTO;
3503
 
                        if (!(t->flags & SN_FINST_MASK))
3504
 
                                t->flags |= SN_FINST_D;
3505
 
                        /* We used to have a free connection slot. Since we'll never use it,
3506
 
                         * we have to inform the server that it may be used by another session.
3507
 
                         */
3508
 
                        if (may_dequeue_tasks(t->srv, t->be))
3509
 
                                process_srv_queue(t->srv);
3510
 
 
3511
 
                        return 1;
3512
 
                }
3513
 
                else if (req->l == 0) {
3514
 
                        if (EV_FD_COND_C(t->srv_fd, DIR_WR)) {
3515
 
                                /* stop writing */
3516
 
                                tv_eternity(&req->wex);
3517
 
                        }
3518
 
                }
3519
 
                else { /* buffer not empty */
3520
 
                        if (EV_FD_COND_S(t->srv_fd, DIR_WR)) {
3521
 
                                /* restart writing */
3522
 
                                if (!tv_add_ifset(&req->wex, &now, &t->be->timeout.server))
3523
 
                                        tv_eternity(&req->wex);
3524
 
                        }
3525
 
                }
3526
 
                return 0;
3527
 
        }
3528
 
        else if (s == SV_STSHUTW) {
3529
 
                if (rep->flags & BF_READ_ERROR) {
3530
 
                        //EV_FD_CLR(t->srv_fd, DIR_RD);
3531
 
                        buffer_shutr(rep);
3532
 
                        fd_delete(t->srv_fd);
3533
 
                        if (t->srv) {
3534
 
                                t->srv->cur_sess--;
3535
 
                                t->srv->failed_resp++;
3536
 
                                sess_change_server(t, NULL);
3537
 
                        }
3538
 
                        t->be->failed_resp++;
3539
 
                        //close(t->srv_fd);
3540
 
                        t->srv_state = SV_STCLOSE;
3541
 
                        if (!(t->flags & SN_ERR_MASK))
3542
 
                                t->flags |= SN_ERR_SRVCL;
3543
 
                        if (!(t->flags & SN_FINST_MASK))
3544
 
                                t->flags |= SN_FINST_D;
3545
 
                        /* We used to have a free connection slot. Since we'll never use it,
3546
 
                         * we have to inform the server that it may be used by another session.
3547
 
                         */
3548
 
                        if (may_dequeue_tasks(t->srv, t->be))
3549
 
                                process_srv_queue(t->srv);
3550
 
 
3551
 
                        return 1;
3552
 
                }
3553
 
                else if (rep->flags & BF_READ_NULL || c == CL_STSHUTW || c == CL_STCLOSE) {
3554
 
                        //EV_FD_CLR(t->srv_fd, DIR_RD);
3555
 
                        buffer_shutr(rep);
3556
 
                        fd_delete(t->srv_fd);
3557
 
                        if (t->srv) {
3558
 
                                t->srv->cur_sess--;
3559
 
                                sess_change_server(t, NULL);
3560
 
                        }
3561
 
                        //close(t->srv_fd);
3562
 
                        t->srv_state = SV_STCLOSE;
3563
 
                        /* We used to have a free connection slot. Since we'll never use it,
3564
 
                         * we have to inform the server that it may be used by another session.
3565
 
                         */
3566
 
                        if (may_dequeue_tasks(t->srv, t->be))
3567
 
                                process_srv_queue(t->srv);
3568
 
 
3569
 
                        return 1;
3570
 
                }
3571
 
                else if (tv_isle(&rep->rex, &now)) {
3572
 
                        //EV_FD_CLR(t->srv_fd, DIR_RD);
3573
 
                        buffer_shutr(rep);
3574
 
                        fd_delete(t->srv_fd);
3575
 
                        if (t->srv) {
3576
 
                                t->srv->cur_sess--;
3577
 
                                sess_change_server(t, NULL);
3578
 
                        }
3579
 
                        //close(t->srv_fd);
3580
 
                        t->srv_state = SV_STCLOSE;
3581
 
                        if (!(t->flags & SN_ERR_MASK))
3582
 
                                t->flags |= SN_ERR_SRVTO;
3583
 
                        if (!(t->flags & SN_FINST_MASK))
3584
 
                                t->flags |= SN_FINST_D;
3585
 
                        /* We used to have a free connection slot. Since we'll never use it,
3586
 
                         * we have to inform the server that it may be used by another session.
3587
 
                         */
3588
 
                        if (may_dequeue_tasks(t->srv, t->be))
3589
 
                                process_srv_queue(t->srv);
3590
 
 
3591
 
                        return 1;
3592
 
                }
3593
 
                else if (rep->l == BUFSIZE) { /* no room to read more data */
3594
 
                        if (EV_FD_COND_C(t->srv_fd, DIR_RD)) {
3595
 
                                tv_eternity(&rep->rex);
3596
 
                        }
3597
 
                }
3598
 
                else {
3599
 
                        if (EV_FD_COND_S(t->srv_fd, DIR_RD)) {
3600
 
                                if (!tv_add_ifset(&rep->rex, &now, &t->be->timeout.server))
3601
 
                                        tv_eternity(&rep->rex);
3602
 
                        }
3603
 
                }
3604
 
                return 0;
3605
 
        }
3606
 
        else if (s == SV_STANALYZE){
3607
 
                /* this server state is set by the client to study the body for server assignment */
3608
 
 
3609
 
                /* Have we been through this long enough to timeout? */
3610
 
                if (!tv_isle(&req->rex, &now)) {
3611
 
                        /* balance url_param check_post should have been the only to get into this.
3612
 
                         * just wait for data, check to compare how much
3613
 
                         */
3614
 
                        struct http_msg * msg = &t->txn.req;
3615
 
                        unsigned long body = msg->sol[msg->eoh] == '\r' ? msg->eoh + 2 :msg->eoh + 1;
3616
 
                        unsigned long len  = req->l - body;
3617
 
                        long long limit = t->be->url_param_post_limit;
3618
 
                        struct hdr_ctx ctx;
3619
 
                        ctx.idx = 0;
3620
 
                        /* now if we have a length, we'll take the hint */
3621
 
                        http_find_header2("Transfer-Encoding", 17, msg->sol, &txn->hdr_idx, &ctx);
3622
 
                        if ( ctx.idx && strncasecmp(ctx.line+ctx.val,"chunked",ctx.vlen)==0) {
3623
 
                                unsigned int chunk = 0;
3624
 
                                while ( body < req->l && !HTTP_IS_CRLF(msg->sol[body])) {
3625
 
                                        char c = msg->sol[body];
3626
 
                                        if (ishex(c)) {
3627
 
                                                unsigned int hex = toupper(c) - '0';
3628
 
                                                if ( hex > 9 )
3629
 
                                                        hex -= 'A' - '9' - 1;
3630
 
                                                chunk = (chunk << 4) | hex;
3631
 
                                        }
3632
 
                                        else break;
3633
 
                                        body++;
3634
 
                                        len--;
3635
 
                                }
3636
 
                                if ( body + 2 >= req->l )
3637
 
                                        return 0; /* end of buffer? data missing! */
3638
 
 
3639
 
                                if ( memcmp(msg->sol+body, "\r\n", 2) != 0 )
3640
 
                                        return 0; /* chunked encoding len ends with CRLF, and we don't have it yet */
3641
 
 
3642
 
                                /* if we support more then one chunk here, we have to do it again when assigning server
3643
 
                                   1. how much entity data do we have? new var
3644
 
                                   2. should save entity_start, entity_cursor, elen & rlen in req; so we don't repeat scanning here
3645
 
                                   3. test if elen > limit, or set new limit to elen if 0 (end of entity found)
3646
 
                                */
3647
 
 
3648
 
                                if ( chunk < limit )
3649
 
                                        limit = chunk;                  /* only reading one chunk */
3650
 
                        } else {
3651
 
                                if ( msg->hdr_content_len < limit )
3652
 
                                        limit = msg->hdr_content_len;
3653
 
                        }
3654
 
                        if ( len < limit )
3655
 
                                return 0;
3656
 
                }
3657
 
                t->srv_state=SV_STIDLE;
3658
 
                return 1;
3659
 
        }
3660
 
        else { /* SV_STCLOSE : nothing to do */
3661
 
                if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
3662
 
                        int len;
3663
 
                        len = sprintf(trash, "%08x:%s.srvcls[%04x:%04x]\n",
3664
 
                                      t->uniq_id, t->be->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
3665
 
                        write(1, trash, len);
3666
 
                }
3667
 
                return 0;
3668
 
        }
 
3009
                return 0;
 
3010
        }
 
3011
 
 
3012
        /* Note: eventhough nobody should set an unknown flag, clearing them right now will
 
3013
         * probably reduce one day's debugging session.
 
3014
         */
 
3015
#ifdef DEBUG_DEV
 
3016
        if (rep->analysers & ~(AN_RTR_HTTP_HDR)) {
 
3017
                fprintf(stderr, "FIXME !!!! unknown analysers flags %s:%d = 0x%08X\n",
 
3018
                        __FILE__, __LINE__, rep->analysers);
 
3019
                ABORT_NOW();
 
3020
        }
 
3021
#endif
 
3022
        rep->analysers &= AN_RTR_HTTP_HDR;
3669
3023
        return 0;
3670
3024
}
3671
3025
 
3672
 
 
3673
3026
/*
3674
3027
 * Produces data for the session <s> depending on its source. Expects to be
3675
 
 * called with s->cli_state == CL_STSHUTR. Right now, only statistics can be
3676
 
 * produced. It stops by itself by unsetting the SN_SELF_GEN flag from the
3677
 
 * session, which it uses to keep on being called when there is free space in
3678
 
 * the buffer, or simply by letting an empty buffer upon return. It returns 1
3679
 
 * if it changes the session state from CL_STSHUTR, otherwise 0.
 
3028
 * called with client socket shut down on input. Right now, only statistics can
 
3029
 * be produced. It stops by itself by unsetting the BF_HIJACK flag from the
 
3030
 * buffer, which it uses to keep on being called when there is free space in
 
3031
 * the buffer, or simply by letting an empty buffer upon return.
3680
3032
 */
3681
 
int produce_content(struct session *s)
 
3033
void produce_content(struct session *s, struct buffer *rep)
3682
3034
{
3683
3035
        if (s->data_source == DATA_SRC_NONE) {
3684
 
                s->flags &= ~SN_SELF_GEN;
3685
 
                return 1;
 
3036
                buffer_stop_hijack(rep);
 
3037
                return;
3686
3038
        }
3687
3039
        else if (s->data_source == DATA_SRC_STATS) {
3688
3040
                /* dump server statistics */
3689
 
                int ret = stats_dump_http(s, s->be->uri_auth);
 
3041
                int ret = stats_dump_http(s, rep, s->be->uri_auth);
3690
3042
                if (ret >= 0)
3691
 
                        return ret;
 
3043
                        return;
3692
3044
                /* -1 indicates an error */
3693
3045
        }
3694
3046
 
3695
3047
        /* unknown data source or internal error */
3696
3048
        s->txn.status = 500;
3697
 
        client_retnclose(s, error_message(s, HTTP_ERR_500));
 
3049
        stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_500));
3698
3050
        if (!(s->flags & SN_ERR_MASK))
3699
3051
                s->flags |= SN_ERR_PRXCOND;
3700
3052
        if (!(s->flags & SN_FINST_MASK))
3701
3053
                s->flags |= SN_FINST_R;
3702
 
        s->flags &= ~SN_SELF_GEN;
3703
 
        return 1;
 
3054
        buffer_stop_hijack(rep);
 
3055
        return;
3704
3056
}
3705
3057
 
3706
3058
 
3774
3126
                                t->rep->rto = t->req->wto = t->be->timeout.server;
3775
3127
                                t->req->cto = t->be->timeout.connect;
3776
3128
                                t->conn_retries = t->be->conn_retries;
 
3129
                                if (t->be->options2 & PR_O2_RSPBUG_OK)
 
3130
                                        t->txn.rsp.err_pos = -1; /* let buggy responses pass */
3777
3131
                                last_hdr = 1;
3778
3132
                                break;
3779
3133
 
3895
3249
                        t->rep->rto = t->req->wto = t->be->timeout.server;
3896
3250
                        t->req->cto = t->be->timeout.connect;
3897
3251
                        t->conn_retries = t->be->conn_retries;
 
3252
                        if (t->be->options2 & PR_O2_RSPBUG_OK)
 
3253
                                t->txn.rsp.err_pos = -1; /* let buggy responses pass */
3898
3254
                        done = 1;
3899
3255
                        break;
3900
3256
 
4235
3591
                                if ((t->be->appsession_name != NULL) &&
4236
3592
                                    (memcmp(p1, t->be->appsession_name, p2 - p1) == 0)) {
4237
3593
                                        /* first, let's see if the cookie is our appcookie*/
4238
 
                            
 
3594
 
4239
3595
                                        /* Cool... it's the right one */
4240
3596
 
4241
3597
                                        asession_temp = &local_asession;
4263
3619
 
4264
3620
                                                asession_temp->sessid = local_asession.sessid;
4265
3621
                                                asession_temp->serverid = local_asession.serverid;
 
3622
                                                asession_temp->request_count = 0;
4266
3623
                                                appsession_hash_insert(&(t->be->htbl_proxy), asession_temp);
4267
3624
                                        } else {
4268
3625
                                                /* free previously allocated memory */
4269
3626
                                                pool_free2(apools.sessid, local_asession.sessid);
4270
3627
                                        }
4271
3628
                                        if (asession_temp->serverid == NULL) {
 
3629
                                                /* TODO redispatch request */
4272
3630
                                                Alert("Found Application Session without matching server.\n");
4273
3631
                                        } else {
4274
3632
                                                struct server *srv = t->be->srv;
4290
3648
                                                }/* end while(srv) */
4291
3649
                                        }/* end else if server == NULL */
4292
3650
 
4293
 
                                        tv_add(&asession_temp->expire, &now, &t->be->timeout.appsession);
 
3651
                                        asession_temp->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
 
3652
                                        asession_temp->request_count++;
 
3653
#if defined(DEBUG_HASH)
 
3654
                                        Alert("manage_client_side_cookies\n");
 
3655
                                        appsession_hash_dump(&(t->be->htbl_proxy));
 
3656
#endif
4294
3657
                                }/* end if ((t->proxy->appsession_name != NULL) ... */
4295
3658
                        }
4296
3659
 
4601
3964
 
4602
3965
 
4603
3966
                /* maybe we only wanted to see if there was a set-cookie. Note that
4604
 
                 * the cookie capture is declared on the frontend.
 
3967
                 * the cookie capture is declared in the fronend.
4605
3968
                 */
4606
3969
                if (t->be->cookie_name == NULL &&
4607
3970
                    t->be->appsession_name == NULL &&
4729
4092
                                        }
4730
4093
                                        asession_temp->sessid = local_asession.sessid;
4731
4094
                                        asession_temp->serverid = local_asession.serverid;
 
4095
                                        asession_temp->request_count = 0;
4732
4096
                                        appsession_hash_insert(&(t->be->htbl_proxy), asession_temp);
4733
4097
                                } else {
4734
4098
                                        /* free wasted memory */
4747
4111
                                if (asession_temp->serverid[0] == '\0')
4748
4112
                                        memcpy(asession_temp->serverid, t->srv->id, server_id_len);
4749
4113
                      
4750
 
                                tv_add(&asession_temp->expire, &now, &t->be->timeout.appsession);
4751
 
 
 
4114
                                asession_temp->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
 
4115
                                asession_temp->request_count++;
4752
4116
#if defined(DEBUG_HASH)
 
4117
                                Alert("manage_server_side_cookies\n");
4753
4118
                                appsession_hash_dump(&(t->be->htbl_proxy));
4754
4119
#endif
4755
4120
                        }/* end if ((t->proxy->appsession_name != NULL) ... */
4903
4268
                }
4904
4269
                asession_temp->sessid = local_asession.sessid;
4905
4270
                asession_temp->serverid = local_asession.serverid;
 
4271
                asession_temp->request_count=0;
4906
4272
                appsession_hash_insert(&(t->be->htbl_proxy), asession_temp);
4907
4273
        }
4908
4274
        else {
4910
4276
                pool_free2(apools.sessid, local_asession.sessid);
4911
4277
        }
4912
4278
 
4913
 
        tv_add(&asession_temp->expire, &now, &t->be->timeout.appsession);
 
4279
        asession_temp->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
4914
4280
        asession_temp->request_count++;
4915
4281
 
4916
4282
#if defined(DEBUG_HASH)
 
4283
        Alert("get_srv_from_appsession\n");
4917
4284
        appsession_hash_dump(&(t->be->htbl_proxy));
4918
4285
#endif
4919
4286
        if (asession_temp->serverid == NULL) {
 
4287
                /* TODO redispatch request */
4920
4288
                Alert("Found Application Session without matching server.\n");
4921
4289
        } else {
4922
4290
                struct server *srv = t->be->srv;
5051
4419
                msg.str = trash;
5052
4420
                msg.len = sprintf(trash, HTTP_401_fmt, uri_auth->auth_realm);
5053
4421
                txn->status = 401;
5054
 
                client_retnclose(t, &msg);
 
4422
                stream_int_retnclose(t->req->prod, &msg);
 
4423
                t->req->analysers = 0;
5055
4424
                if (!(t->flags & SN_ERR_MASK))
5056
4425
                        t->flags |= SN_ERR_PRXCOND;
5057
4426
                if (!(t->flags & SN_FINST_MASK))
5062
4431
        /* The request is valid, the user is authenticated. Let's start sending
5063
4432
         * data.
5064
4433
         */
5065
 
        EV_FD_CLR(t->cli_fd, DIR_RD);
5066
 
        buffer_shutr(t->req);
5067
 
        buffer_shutr(t->rep);
5068
 
        t->cli_state = CL_STSHUTR;
5069
 
        t->req->rlim = t->req->data + BUFSIZE; /* no more rewrite needed */
 
4434
        buffer_write_dis(t->req);
 
4435
        buffer_shutw_now(t->req);
 
4436
        buffer_shutr_now(t->rep);
5070
4437
        t->logs.tv_request = now;
5071
4438
        t->data_source = DATA_SRC_STATS;
5072
4439
        t->data_state  = DATA_ST_INIT;
5073
 
        produce_content(t);
 
4440
        t->task->nice = -32; /* small boost for HTTP statistics */
 
4441
        buffer_install_hijacker(t, t->rep, produce_content);
5074
4442
        return 1;
5075
4443
}
5076
4444
 
 
4445
/*
 
4446
 * Capture a bad request or response and archive it in the proxy's structure.
 
4447
 */
 
4448
void http_capture_bad_message(struct error_snapshot *es, struct session *s,
 
4449
                              struct buffer *buf, struct http_msg *msg,
 
4450
                              struct proxy *other_end)
 
4451
{
 
4452
        es->len = buf->r - (buf->data + msg->som);
 
4453
        memcpy(es->buf, buf->data + msg->som, MIN(es->len, sizeof(es->buf)));
 
4454
        if (msg->err_pos >= 0)
 
4455
                es->pos  = msg->err_pos - msg->som;
 
4456
        else
 
4457
                es->pos  = buf->lr - (buf->data + msg->som);
 
4458
        es->when = date; // user-visible date
 
4459
        es->sid  = s->uniq_id;
 
4460
        es->srv  = s->srv;
 
4461
        es->oe   = other_end;
 
4462
        es->src  = s->cli_addr;
 
4463
}
5077
4464
 
5078
4465
/*
5079
4466
 * Print a debug line with a header
5082
4469
{
5083
4470
        int len, max;
5084
4471
        len = sprintf(trash, "%08x:%s.%s[%04x:%04x]: ", t->uniq_id, t->be->id,
5085
 
                      dir, (unsigned  short)t->cli_fd, (unsigned short)t->srv_fd);
 
4472
                      dir, (unsigned  short)t->req->prod->fd, (unsigned short)t->req->cons->fd);
5086
4473
        max = end - start;
5087
4474
        UBOUND(max, sizeof(trash) - len - 1);
5088
4475
        len += strlcpy2(trash + len, start, max + 1);
5126
4513
        int meth;
5127
4514
        struct http_txn *txn = l7;
5128
4515
 
 
4516
        if (!txn)
 
4517
                return 0;
 
4518
 
5129
4519
        if (txn->req.msg_state != HTTP_MSG_BODY)
5130
4520
                return 0;
5131
4521
 
5147
4537
        int icase;
5148
4538
 
5149
4539
        if (test->i != pattern->val.i)
5150
 
                return 0;
 
4540
                return ACL_PAT_FAIL;
5151
4541
 
5152
4542
        if (test->i != HTTP_METH_OTHER)
5153
 
                return 1;
 
4543
                return ACL_PAT_PASS;
5154
4544
 
5155
4545
        /* Other method, we must compare the strings */
5156
4546
        if (pattern->len != test->len)
5157
 
                return 0;
 
4547
                return ACL_PAT_FAIL;
5158
4548
 
5159
4549
        icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
5160
4550
        if ((icase && strncasecmp(pattern->ptr.str, test->ptr, test->len) != 0) ||
5161
4551
            (!icase && strncmp(pattern->ptr.str, test->ptr, test->len) != 0))
5162
 
                return 0;
5163
 
        return 1;
 
4552
                return ACL_PAT_FAIL;
 
4553
        return ACL_PAT_PASS;
5164
4554
}
5165
4555
 
5166
4556
/* 2. Check on Request/Status Version
5183
4573
        char *ptr;
5184
4574
        int len;
5185
4575
 
 
4576
        if (!txn)
 
4577
                return 0;
 
4578
 
5186
4579
        if (txn->req.msg_state != HTTP_MSG_BODY)
5187
4580
                return 0;
5188
4581
 
5208
4601
        char *ptr;
5209
4602
        int len;
5210
4603
 
 
4604
        if (!txn)
 
4605
                return 0;
 
4606
 
5211
4607
        if (txn->rsp.msg_state != HTTP_MSG_BODY)
5212
4608
                return 0;
5213
4609
 
5234
4630
        char *ptr;
5235
4631
        int len;
5236
4632
 
 
4633
        if (!txn)
 
4634
                return 0;
 
4635
 
5237
4636
        if (txn->rsp.msg_state != HTTP_MSG_BODY)
5238
4637
                return 0;
5239
4638
 
5252
4651
{
5253
4652
        struct http_txn *txn = l7;
5254
4653
 
 
4654
        if (!txn)
 
4655
                return 0;
 
4656
 
5255
4657
        if (txn->req.msg_state != HTTP_MSG_BODY)
5256
4658
                return 0;
 
4659
 
5257
4660
        if (txn->rsp.msg_state != HTTP_MSG_RPBEFORE)
5258
4661
                /* ensure the indexes are not affected */
5259
4662
                return 0;
5272
4675
{
5273
4676
        struct http_txn *txn = l7;
5274
4677
 
 
4678
        if (!txn)
 
4679
                return 0;
 
4680
 
5275
4681
        if (txn->req.msg_state != HTTP_MSG_BODY)
5276
4682
                return 0;
 
4683
 
5277
4684
        if (txn->rsp.msg_state != HTTP_MSG_RPBEFORE)
5278
4685
                /* ensure the indexes are not affected */
5279
4686
                return 0;
5300
4707
{
5301
4708
        struct http_txn *txn = l7;
5302
4709
 
 
4710
        if (!txn)
 
4711
                return 0;
 
4712
 
5303
4713
        if (txn->req.msg_state != HTTP_MSG_BODY)
5304
4714
                return 0;
 
4715
 
5305
4716
        if (txn->rsp.msg_state != HTTP_MSG_RPBEFORE)
5306
4717
                /* ensure the indexes are not affected */
5307
4718
                return 0;
5328
4739
        struct hdr_idx *idx = &txn->hdr_idx;
5329
4740
        struct hdr_ctx *ctx = (struct hdr_ctx *)test->ctx.a;
5330
4741
 
 
4742
        if (!txn)
 
4743
                return 0;
 
4744
 
5331
4745
        if (!(test->flags & ACL_TEST_F_FETCH_MORE))
5332
4746
                /* search for header from the beginning */
5333
4747
                ctx->idx = 0;
5351
4765
{
5352
4766
        struct http_txn *txn = l7;
5353
4767
 
 
4768
        if (!txn)
 
4769
                return 0;
 
4770
 
5354
4771
        if (txn->req.msg_state != HTTP_MSG_BODY)
5355
4772
                return 0;
 
4773
 
5356
4774
        if (txn->rsp.msg_state != HTTP_MSG_RPBEFORE)
5357
4775
                /* ensure the indexes are not affected */
5358
4776
                return 0;
5366
4784
{
5367
4785
        struct http_txn *txn = l7;
5368
4786
 
 
4787
        if (!txn)
 
4788
                return 0;
 
4789
 
5369
4790
        if (txn->rsp.msg_state != HTTP_MSG_BODY)
5370
4791
                return 0;
5371
4792
 
5384
4805
        struct hdr_ctx ctx;
5385
4806
        int cnt;
5386
4807
 
 
4808
        if (!txn)
 
4809
                return 0;
 
4810
 
5387
4811
        ctx.idx = 0;
5388
4812
        cnt = 0;
5389
4813
        while (http_find_header2(expr->arg.str, expr->arg_len, sol, idx, &ctx))
5400
4824
{
5401
4825
        struct http_txn *txn = l7;
5402
4826
 
 
4827
        if (!txn)
 
4828
                return 0;
 
4829
 
5403
4830
        if (txn->req.msg_state != HTTP_MSG_BODY)
5404
4831
                return 0;
 
4832
 
5405
4833
        if (txn->rsp.msg_state != HTTP_MSG_RPBEFORE)
5406
4834
                /* ensure the indexes are not affected */
5407
4835
                return 0;
5415
4843
{
5416
4844
        struct http_txn *txn = l7;
5417
4845
 
 
4846
        if (!txn)
 
4847
                return 0;
 
4848
 
5418
4849
        if (txn->rsp.msg_state != HTTP_MSG_BODY)
5419
4850
                return 0;
5420
4851
 
5433
4864
        struct hdr_idx *idx = &txn->hdr_idx;
5434
4865
        struct hdr_ctx *ctx = (struct hdr_ctx *)test->ctx.a;
5435
4866
 
 
4867
        if (!txn)
 
4868
                return 0;
 
4869
 
5436
4870
        if (!(test->flags & ACL_TEST_F_FETCH_MORE))
5437
4871
                /* search for header from the beginning */
5438
4872
                ctx->idx = 0;
5455
4889
{
5456
4890
        struct http_txn *txn = l7;
5457
4891
 
 
4892
        if (!txn)
 
4893
                return 0;
 
4894
 
5458
4895
        if (txn->req.msg_state != HTTP_MSG_BODY)
5459
4896
                return 0;
 
4897
 
5460
4898
        if (txn->rsp.msg_state != HTTP_MSG_RPBEFORE)
5461
4899
                /* ensure the indexes are not affected */
5462
4900
                return 0;
5470
4908
{
5471
4909
        struct http_txn *txn = l7;
5472
4910
 
 
4911
        if (!txn)
 
4912
                return 0;
 
4913
 
5473
4914
        if (txn->rsp.msg_state != HTTP_MSG_BODY)
5474
4915
                return 0;
5475
4916
 
5486
4927
        struct http_txn *txn = l7;
5487
4928
        char *ptr, *end;
5488
4929
 
 
4930
        if (!txn)
 
4931
                return 0;
 
4932
 
5489
4933
        if (txn->req.msg_state != HTTP_MSG_BODY)
5490
4934
                return 0;
 
4935
 
5491
4936
        if (txn->rsp.msg_state != HTTP_MSG_RPBEFORE)
5492
4937
                /* ensure the indexes are not affected */
5493
4938
                return 0;
5518
4963
 
5519
4964
/* Note: must not be declared <const> as its list will be overwritten */
5520
4965
static struct acl_kw_list acl_kws = {{ },{
5521
 
        { "method",     acl_parse_meth,  acl_fetch_meth,   acl_match_meth },
5522
 
        { "req_ver",    acl_parse_ver,   acl_fetch_rqver,  acl_match_str  },
5523
 
        { "resp_ver",   acl_parse_ver,   acl_fetch_stver,  acl_match_str  },
5524
 
        { "status",     acl_parse_int,   acl_fetch_stcode, acl_match_int  },
5525
 
 
5526
 
        { "url",        acl_parse_str,   acl_fetch_url,      acl_match_str  },
5527
 
        { "url_beg",    acl_parse_str,   acl_fetch_url,      acl_match_beg  },
5528
 
        { "url_end",    acl_parse_str,   acl_fetch_url,      acl_match_end  },
5529
 
        { "url_sub",    acl_parse_str,   acl_fetch_url,      acl_match_sub  },
5530
 
        { "url_dir",    acl_parse_str,   acl_fetch_url,      acl_match_dir  },
5531
 
        { "url_dom",    acl_parse_str,   acl_fetch_url,      acl_match_dom  },
5532
 
        { "url_reg",    acl_parse_reg,   acl_fetch_url,      acl_match_reg  },
5533
 
        { "url_ip",     acl_parse_ip,    acl_fetch_url_ip,   acl_match_ip   },
5534
 
        { "url_port",   acl_parse_int,   acl_fetch_url_port, acl_match_int  },
5535
 
 
5536
 
        { "hdr",        acl_parse_str,   acl_fetch_chdr,    acl_match_str },
5537
 
        { "hdr_reg",    acl_parse_reg,   acl_fetch_chdr,    acl_match_reg },
5538
 
        { "hdr_beg",    acl_parse_str,   acl_fetch_chdr,    acl_match_beg },
5539
 
        { "hdr_end",    acl_parse_str,   acl_fetch_chdr,    acl_match_end },
5540
 
        { "hdr_sub",    acl_parse_str,   acl_fetch_chdr,    acl_match_sub },
5541
 
        { "hdr_dir",    acl_parse_str,   acl_fetch_chdr,    acl_match_dir },
5542
 
        { "hdr_dom",    acl_parse_str,   acl_fetch_chdr,    acl_match_dom },
5543
 
        { "hdr_cnt",    acl_parse_int,   acl_fetch_chdr_cnt,acl_match_int },
5544
 
        { "hdr_val",    acl_parse_int,   acl_fetch_chdr_val,acl_match_int },
5545
 
 
5546
 
        { "shdr",       acl_parse_str,   acl_fetch_shdr,    acl_match_str },
5547
 
        { "shdr_reg",   acl_parse_reg,   acl_fetch_shdr,    acl_match_reg },
5548
 
        { "shdr_beg",   acl_parse_str,   acl_fetch_shdr,    acl_match_beg },
5549
 
        { "shdr_end",   acl_parse_str,   acl_fetch_shdr,    acl_match_end },
5550
 
        { "shdr_sub",   acl_parse_str,   acl_fetch_shdr,    acl_match_sub },
5551
 
        { "shdr_dir",   acl_parse_str,   acl_fetch_shdr,    acl_match_dir },
5552
 
        { "shdr_dom",   acl_parse_str,   acl_fetch_shdr,    acl_match_dom },
5553
 
        { "shdr_cnt",   acl_parse_int,   acl_fetch_shdr_cnt,acl_match_int },
5554
 
        { "shdr_val",   acl_parse_int,   acl_fetch_shdr_val,acl_match_int },
5555
 
 
5556
 
        { "path",       acl_parse_str,   acl_fetch_path,   acl_match_str  },
5557
 
        { "path_reg",   acl_parse_reg,   acl_fetch_path,   acl_match_reg  },
5558
 
        { "path_beg",   acl_parse_str,   acl_fetch_path,   acl_match_beg  },
5559
 
        { "path_end",   acl_parse_str,   acl_fetch_path,   acl_match_end  },
5560
 
        { "path_sub",   acl_parse_str,   acl_fetch_path,   acl_match_sub  },
5561
 
        { "path_dir",   acl_parse_str,   acl_fetch_path,   acl_match_dir  },
5562
 
        { "path_dom",   acl_parse_str,   acl_fetch_path,   acl_match_dom  },
 
4966
        { "method",     acl_parse_meth,  acl_fetch_meth,   acl_match_meth, ACL_USE_L7REQ_PERMANENT },
 
4967
        { "req_ver",    acl_parse_ver,   acl_fetch_rqver,  acl_match_str,  ACL_USE_L7REQ_VOLATILE  },
 
4968
        { "resp_ver",   acl_parse_ver,   acl_fetch_stver,  acl_match_str,  ACL_USE_L7RTR_VOLATILE  },
 
4969
        { "status",     acl_parse_int,   acl_fetch_stcode, acl_match_int,  ACL_USE_L7RTR_PERMANENT },
 
4970
 
 
4971
        { "url",        acl_parse_str,   acl_fetch_url,      acl_match_str,  ACL_USE_L7REQ_VOLATILE },
 
4972
        { "url_beg",    acl_parse_str,   acl_fetch_url,      acl_match_beg,  ACL_USE_L7REQ_VOLATILE },
 
4973
        { "url_end",    acl_parse_str,   acl_fetch_url,      acl_match_end,  ACL_USE_L7REQ_VOLATILE },
 
4974
        { "url_sub",    acl_parse_str,   acl_fetch_url,      acl_match_sub,  ACL_USE_L7REQ_VOLATILE },
 
4975
        { "url_dir",    acl_parse_str,   acl_fetch_url,      acl_match_dir,  ACL_USE_L7REQ_VOLATILE },
 
4976
        { "url_dom",    acl_parse_str,   acl_fetch_url,      acl_match_dom,  ACL_USE_L7REQ_VOLATILE },
 
4977
        { "url_reg",    acl_parse_reg,   acl_fetch_url,      acl_match_reg,  ACL_USE_L7REQ_VOLATILE },
 
4978
        { "url_ip",     acl_parse_ip,    acl_fetch_url_ip,   acl_match_ip,   ACL_USE_L7REQ_VOLATILE },
 
4979
        { "url_port",   acl_parse_int,   acl_fetch_url_port, acl_match_int,  ACL_USE_L7REQ_VOLATILE },
 
4980
 
 
4981
        /* note: we should set hdr* to use ACL_USE_HDR_VOLATILE, and chdr* to use L7REQ_VOLATILE */
 
4982
        { "hdr",        acl_parse_str,   acl_fetch_chdr,    acl_match_str, ACL_USE_L7REQ_VOLATILE },
 
4983
        { "hdr_reg",    acl_parse_reg,   acl_fetch_chdr,    acl_match_reg, ACL_USE_L7REQ_VOLATILE },
 
4984
        { "hdr_beg",    acl_parse_str,   acl_fetch_chdr,    acl_match_beg, ACL_USE_L7REQ_VOLATILE },
 
4985
        { "hdr_end",    acl_parse_str,   acl_fetch_chdr,    acl_match_end, ACL_USE_L7REQ_VOLATILE },
 
4986
        { "hdr_sub",    acl_parse_str,   acl_fetch_chdr,    acl_match_sub, ACL_USE_L7REQ_VOLATILE },
 
4987
        { "hdr_dir",    acl_parse_str,   acl_fetch_chdr,    acl_match_dir, ACL_USE_L7REQ_VOLATILE },
 
4988
        { "hdr_dom",    acl_parse_str,   acl_fetch_chdr,    acl_match_dom, ACL_USE_L7REQ_VOLATILE },
 
4989
        { "hdr_cnt",    acl_parse_int,   acl_fetch_chdr_cnt,acl_match_int, ACL_USE_L7REQ_VOLATILE },
 
4990
        { "hdr_val",    acl_parse_int,   acl_fetch_chdr_val,acl_match_int, ACL_USE_L7REQ_VOLATILE },
 
4991
 
 
4992
        { "shdr",       acl_parse_str,   acl_fetch_shdr,    acl_match_str, ACL_USE_L7RTR_VOLATILE },
 
4993
        { "shdr_reg",   acl_parse_reg,   acl_fetch_shdr,    acl_match_reg, ACL_USE_L7RTR_VOLATILE },
 
4994
        { "shdr_beg",   acl_parse_str,   acl_fetch_shdr,    acl_match_beg, ACL_USE_L7RTR_VOLATILE },
 
4995
        { "shdr_end",   acl_parse_str,   acl_fetch_shdr,    acl_match_end, ACL_USE_L7RTR_VOLATILE },
 
4996
        { "shdr_sub",   acl_parse_str,   acl_fetch_shdr,    acl_match_sub, ACL_USE_L7RTR_VOLATILE },
 
4997
        { "shdr_dir",   acl_parse_str,   acl_fetch_shdr,    acl_match_dir, ACL_USE_L7RTR_VOLATILE },
 
4998
        { "shdr_dom",   acl_parse_str,   acl_fetch_shdr,    acl_match_dom, ACL_USE_L7RTR_VOLATILE },
 
4999
        { "shdr_cnt",   acl_parse_int,   acl_fetch_shdr_cnt,acl_match_int, ACL_USE_L7RTR_VOLATILE },
 
5000
        { "shdr_val",   acl_parse_int,   acl_fetch_shdr_val,acl_match_int, ACL_USE_L7RTR_VOLATILE },
 
5001
 
 
5002
        { "path",       acl_parse_str,   acl_fetch_path,   acl_match_str, ACL_USE_L7REQ_VOLATILE },
 
5003
        { "path_reg",   acl_parse_reg,   acl_fetch_path,   acl_match_reg, ACL_USE_L7REQ_VOLATILE },
 
5004
        { "path_beg",   acl_parse_str,   acl_fetch_path,   acl_match_beg, ACL_USE_L7REQ_VOLATILE },
 
5005
        { "path_end",   acl_parse_str,   acl_fetch_path,   acl_match_end, ACL_USE_L7REQ_VOLATILE },
 
5006
        { "path_sub",   acl_parse_str,   acl_fetch_path,   acl_match_sub, ACL_USE_L7REQ_VOLATILE },
 
5007
        { "path_dir",   acl_parse_str,   acl_fetch_path,   acl_match_dir, ACL_USE_L7REQ_VOLATILE },
 
5008
        { "path_dom",   acl_parse_str,   acl_fetch_path,   acl_match_dom, ACL_USE_L7REQ_VOLATILE },
5563
5009
 
5564
5010
        { NULL, NULL, NULL, NULL },
5565
5011