varnish-cache/bin/varnishd/http1/cache_http1_proto.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2015 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 *
29
 * HTTP protocol requests
30
 *
31
 * The trouble with the "until magic sequence" design of HTTP protocol messages
32
 * is that either you have to read a single character at a time, which is
33
 * inefficient, or you risk reading too much, and pre-read some of the object,
34
 * or even the next pipelined request, which follows the one you want.
35
 *
36
 * HTC reads a HTTP protocol header into a workspace, subject to limits,
37
 * and stops when we see the magic marker (double [CR]NL), and if we overshoot,
38
 * it keeps track of the "pipelined" data.
39
 *
40
 * We use this both for client and backend connections.
41
 */
42
43
#include "config.h"
44
45
#include "cache/cache_varnishd.h"
46
#include "cache/cache_transport.h"
47
48
#include "cache_http1.h"
49
50
#include "vct.h"
51
52
const int HTTP1_Req[3] = {
53
        HTTP_HDR_METHOD, HTTP_HDR_URL, HTTP_HDR_PROTO
54
};
55
56
const int HTTP1_Resp[3] = {
57
        HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_REASON
58
};
59
60
/*--------------------------------------------------------------------
61
 * Check if we have a complete HTTP request or response yet
62
 */
63
64
enum htc_status_e v_matchproto_(htc_complete_f)
65 9396
HTTP1_Complete(struct http_conn *htc)
66
{
67
        char *p;
68
        enum htc_status_e retval;
69
70 9396
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
71
72 9396
        assert(htc->rxbuf_e >= htc->rxbuf_b);
73 9396
        assert(htc->rxbuf_e <= htc->ws->r);
74
75
        /* Skip any leading white space */
76 9398
        for (p = htc->rxbuf_b ; p < htc->rxbuf_e && vct_islws(*p); p++)
77 2
                continue;
78 9396
        if (p == htc->rxbuf_e)
79 5106
                return (HTC_S_EMPTY);
80
81
        /* Do not return a partial H2 connection preface */
82 4290
        retval = H2_prism_complete(htc);
83 4290
        if (retval != HTC_S_JUNK)
84 142
                return (retval);
85
86
        /*
87
         * Here we just look for NL[CR]NL to see that reception
88
         * is completed.  More stringent validation happens later.
89
         */
90
        while (1) {
91 14596
                p = memchr(p, '\n', htc->rxbuf_e - p);
92 9372
                if (p == NULL)
93 379
                        return (HTC_S_MORE);
94 8993
                if (++p == htc->rxbuf_e)
95 22
                        return (HTC_S_MORE);
96 8971
                if (*p == '\r' && ++p == htc->rxbuf_e)
97 2
                        return (HTC_S_MORE);
98 8969
                if (*p == '\n')
99 3745
                        break;
100
        }
101 3745
        return (HTC_S_COMPLETE);
102
}
103
104
/*--------------------------------------------------------------------
105
 * Dissect the headers of the HTTP protocol message.
106
 * Detect conditionals (headers which start with '^[Ii][Ff]-')
107
 */
108
109
static uint16_t
110 3740
http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc,
111
    unsigned maxhdr)
112
{
113
        char *q, *r, *s;
114
115 3740
        assert(p > htc->rxbuf_b);
116 3740
        assert(p <= htc->rxbuf_e);
117 3740
        hp->nhd = HTTP_HDR_FIRST;
118 3740
        hp->conds = 0;
119 3740
        r = NULL;               /* For FlexeLint */
120 8747
        for (; p < htc->rxbuf_e; p = r) {
121
122
                /* Find end of next header */
123 8747
                q = r = p;
124 8747
                if (vct_iscrlf(p))
125
                        break;
126 111152
                while (r < htc->rxbuf_e) {
127 106125
                        if (!vct_isctl(*r) || vct_issp(*r)) {
128 101097
                                r++;
129 101097
                                continue;
130
                        }
131 5028
                        if (!vct_iscrlf(r)) {
132 4
                                VSLb(hp->vsl, SLT_BogoHeader,
133 4
                                    "Header has ctrl char 0x%02x", *r);
134 4
                                return (400);
135
                        }
136 5024
                        q = r;
137 5024
                        assert(r < htc->rxbuf_e);
138 5024
                        r += vct_skipcrlf(r);
139 5024
                        if (r >= htc->rxbuf_e)
140 0
                                break;
141 5024
                        if (vct_iscrlf(r))
142
                                break;
143
                        /* If line does not continue: got it. */
144 1322
                        if (!vct_issp(*r))
145 1317
                                break;
146
147
                        /* Clear line continuation LWS to spaces */
148 20
                        while (vct_islws(*q))
149 10
                                *q++ = ' ';
150
                }
151
152
                /* Empty header = end of headers */
153 5021
                if (p == q)
154 2
                        break;
155
156 5019
                if (q - p > maxhdr) {
157 4
                        VSLb(hp->vsl, SLT_BogoHeader, "Header too long: %.*s",
158 4
                            (int)(q - p > 20 ? 20 : q - p), p);
159 4
                        return (400);
160
                }
161
162 5015
                if (vct_islws(*p)) {
163 4
                        VSLb(hp->vsl, SLT_BogoHeader,
164
                            "1st header has white space: %.*s",
165 4
                            (int)(q - p > 20 ? 20 : q - p), p);
166 2
                        return (400);
167
                }
168
169 5013
                if (*p == ':') {
170 2
                        VSLb(hp->vsl, SLT_BogoHeader,
171
                            "Missing header name: %.*s",
172 2
                            (int)(q - p > 20 ? 20 : q - p), p);
173 1
                        return (400);
174
                }
175
176 5073
                if ((p[0] == 'i' || p[0] == 'I') &&
177 122
                    (p[1] == 'f' || p[1] == 'F') &&
178 53
                    p[2] == '-')
179 53
                        hp->conds = 1;
180
181 10036
                while (q > p && vct_issp(q[-1]))
182 12
                        q--;
183 5012
                *q = '\0';
184
185 45838
                for (s = p; *s != ':' && s < q; s++) {
186 40830
                        if (!vct_istchar(*s)) {
187 4
                                VSLb(hp->vsl, SLT_BogoHeader,
188 4
                                    "Illegal char 0x%02x in header name", *s);
189 4
                                return (400);
190
                        }
191
                }
192 5008
                if (*s != ':') {
193 2
                        VSLb(hp->vsl, SLT_BogoHeader, "Header without ':' %.*s",
194 2
                            (int)(q - p > 20 ? 20 : q - p), p);
195 1
                        return (400);
196
                }
197
198 5007
                if (hp->nhd < hp->shd) {
199 5007
                        hp->hdf[hp->nhd] = 0;
200 5007
                        hp->hd[hp->nhd].b = p;
201 5007
                        hp->hd[hp->nhd].e = q;
202 5007
                        hp->nhd++;
203
                } else {
204 0
                        VSLb(hp->vsl, SLT_BogoHeader, "Too many headers: %.*s",
205 0
                            (int)(q - p > 20 ? 20 : q - p), p);
206 0
                        return (400);
207
                }
208
        }
209
        /* We cannot use vct_skipcrlf() we have to respect rxbuf_e */
210 3724
        if (p+2 <= htc->rxbuf_e && p[0] == '\r' && p[1] == '\n')
211 3703
                p += 2;
212 21
        else if (p+1 <= htc->rxbuf_e && p[0] == '\n')
213 19
                p += 1;
214 3724
        HTC_RxPipeline(htc, p);
215 3724
        htc->rxbuf_e = p;
216 3724
        return (0);
217
}
218
219
/*--------------------------------------------------------------------
220
 * Deal with first line of HTTP protocol message.
221
 */
222
223
static uint16_t
224 3745
http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
225
    unsigned maxhdr)
226
{
227
        char *p;
228
        int i;
229
230 3745
        assert(hf == HTTP1_Req || hf == HTTP1_Resp);
231 3745
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
232 3745
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
233 3745
        assert(htc->rxbuf_e >= htc->rxbuf_b);
234
235 3745
        AZ(hp->hd[hf[0]].b);
236 3745
        AZ(hp->hd[hf[1]].b);
237 3745
        AZ(hp->hd[hf[2]].b);
238
239
        /* Skip leading LWS */
240 3745
        for (p = htc->rxbuf_b ; vct_islws(*p); p++)
241 0
                continue;
242 3745
        hp->hd[hf[0]].b = p;
243
244
        /* First field cannot contain SP or CTL */
245 22997
        for (; !vct_issp(*p); p++) {
246 19255
                if (vct_isctl(*p))
247 3
                        return (400);
248
        }
249 3742
        hp->hd[hf[0]].e = p;
250 3742
        assert(Tlen(hp->hd[hf[0]]));
251 3742
        *p++ = '\0';
252
253
        /* Skip SP */
254 3745
        for (; vct_issp(*p); p++) {
255 3
                if (vct_isctl(*p))
256 0
                        return (400);
257
        }
258 3742
        hp->hd[hf[1]].b = p;
259
260
        /* Second field cannot contain LWS or CTL */
261 16102
        for (; !vct_islws(*p); p++) {
262 12360
                if (vct_isctl(*p))
263 0
                        return (400);
264
        }
265 3742
        hp->hd[hf[1]].e = p;
266 3742
        if (!Tlen(hp->hd[hf[1]]))
267 1
                return (400);
268 3741
        *p++ = '\0';
269
270
        /* Skip SP */
271 3741
        for (; vct_issp(*p); p++) {
272 0
                if (vct_isctl(*p))
273 0
                        return (400);
274
        }
275 3741
        hp->hd[hf[2]].b = p;
276
277
        /* Third field is optional and cannot contain CTL except TAB */
278 24235
        for (; !vct_iscrlf(p); p++) {
279 20495
                if (vct_isctl(*p) && !vct_issp(*p)) {
280 1
                        hp->hd[hf[2]].b = NULL;
281 1
                        return (400);
282
                }
283
        }
284 3740
        hp->hd[hf[2]].e = p;
285
286
        /* Skip CRLF */
287 3740
        i = vct_skipcrlf(p);
288 3740
        *p = '\0';
289 3740
        p += i;
290
291 3740
        http_Proto(hp);
292
293 3740
        return (http1_dissect_hdrs(hp, p, htc, maxhdr));
294
}
295
296
/*--------------------------------------------------------------------*/
297
298
static enum body_status
299 3723
http1_body_status(const struct http *hp, struct http_conn *htc, int request)
300
{
301
        ssize_t cl;
302
        const char *b;
303
304 3723
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
305 3723
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
306
307 3723
        htc->content_length = -1;
308
309 3723
        cl = http_GetContentLength(hp);
310 3723
        if (cl == -2)
311 4
                return (BS_ERROR);
312 3719
        if (http_GetHdr(hp, H_Transfer_Encoding, &b)) {
313 129
                if (strcasecmp(b, "chunked"))
314 2
                        return (BS_ERROR);
315 127
                if (cl != -1) {
316
                        /*
317
                         * RFC7230 3.3.3 allows more lenient handling
318
                         * but we're going to be strict.
319
                         */
320 2
                        return (BS_ERROR);
321
                }
322 125
                return (BS_CHUNKED);
323
        }
324 3590
        if (cl >= 0) {
325 1458
                htc->content_length = cl;
326 1458
                return (cl == 0 ? BS_NONE : BS_LENGTH);
327
        }
328
329 2132
        if (hp->protover == 11 && request)
330 2082
                return (BS_NONE);
331
332 50
        if (http_HdrIs(hp, H_Connection, "keep-alive")) {
333
                /*
334
                 * Keep alive with neither TE=Chunked or C-Len is impossible.
335
                 * We assume a zero length body.
336
                 */
337 2
                return (BS_NONE);
338
        }
339
340
        /*
341
         * Fall back to EOF transfer.
342
         */
343 48
        return (BS_EOF);
344
}
345
346
/*--------------------------------------------------------------------*/
347
348
uint16_t
349 2168
HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)
350
{
351
        uint16_t retval;
352
        const char *p;
353 2168
        const char *b = NULL, *e;
354
355 2168
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
356 2168
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
357
358 2168
        retval = http1_splitline(hp, htc,
359 2168
            HTTP1_Req, cache_param->http_req_hdr_len);
360 2168
        if (retval != 0)
361 15
                return (retval);
362
363 2153
        if (hp->protover < 10 || hp->protover > 11)
364 5
                return (400);
365
366 2148
        if (http_CountHdr(hp, H_Host) > 1)
367 1
                return (400);
368
369 2147
        if (http_CountHdr(hp, H_Content_Length) > 1)
370 1
                return (400);
371
372
        /* RFC2616, section 5.2, point 1 */
373 2146
        if (!strncasecmp(hp->hd[HTTP_HDR_URL].b, "http://", 7))
374 3
                b = hp->hd[HTTP_HDR_URL].b + 7;
375 2144
        else if (FEATURE(FEATURE_HTTPS_SCHEME) &&
376 1
            !strncasecmp(hp->hd[HTTP_HDR_URL].b, "https://", 8))
377 1
                b = hp->hd[HTTP_HDR_URL].b + 8;
378 2146
        if (b) {
379 4
                e = strchr(b, '/');
380 4
                if (e) {
381 4
                        http_Unset(hp, H_Host);
382 4
                        http_PrintfHeader(hp, "Host: %.*s", (int)(e - b), b);
383 4
                        hp->hd[HTTP_HDR_URL].b = e;
384
                }
385
        }
386
387 2146
        htc->body_status = http1_body_status(hp, htc, 1);
388 2146
        if (htc->body_status == BS_ERROR)
389 4
                return (400);
390
391 2142
        p = http_GetMethod(hp);
392 2142
        AN(p);
393
394 2142
        if (htc->body_status == BS_EOF) {
395 14
                assert(hp->protover == 10);
396
                /* RFC1945 8.3 p32 and D.1.1 p58 */
397 14
                if (!strcasecmp(p, "post") || !strcasecmp(p, "put"))
398 2
                        return (400);
399 12
                htc->body_status = BS_NONE;
400
        }
401
402
        /* HEAD with a body is a hard error */
403 2140
        if (htc->body_status != BS_NONE && !strcasecmp(p, "head"))
404 0
                return (400);
405
406 2140
        return (retval);
407
}
408
409
/*--------------------------------------------------------------------*/
410
411
uint16_t
412 1577
HTTP1_DissectResponse(struct http_conn *htc, struct http *hp,
413
    const struct http *rhttp)
414
{
415 1577
        uint16_t retval = 0;
416
        const char *p;
417
418 1577
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
419 1577
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
420 1577
        CHECK_OBJ_NOTNULL(rhttp, HTTP_MAGIC);
421
422 1577
        if (http1_splitline(hp, htc,
423 1577
            HTTP1_Resp, cache_param->http_resp_hdr_len))
424 6
                retval = 503;
425
426 1577
        if (retval == 0 && hp->protover < 10)
427 0
                retval = 503;
428
429 1577
        if (retval == 0 && hp->protover > rhttp->protover)
430 1
                http_SetH(hp, HTTP_HDR_PROTO, rhttp->hd[HTTP_HDR_PROTO].b);
431
432 1577
        if (retval == 0 && Tlen(hp->hd[HTTP_HDR_STATUS]) != 3)
433 3
                retval = 503;
434
435 1577
        if (retval == 0) {
436 1568
                p = hp->hd[HTTP_HDR_STATUS].b;
437
438 3133
                if (p[0] >= '1' && p[0] <= '9' &&
439 4692
                    p[1] >= '0' && p[1] <= '9' &&
440 3125
                    p[2] >= '0' && p[2] <= '9')
441 1561
                        hp->status =
442 1561
                            100 * (p[0] - '0') + 10 * (p[1] - '0') + p[2] - '0';
443
                else
444 7
                        retval = 503;
445
        }
446
447 1577
        if (retval != 0) {
448 32
                VSLb(hp->vsl, SLT_HttpGarbage, "%.*s",
449 16
                    (int)(htc->rxbuf_e - htc->rxbuf_b), htc->rxbuf_b);
450 16
                assert(retval >= 100 && retval <= 999);
451 16
                assert(retval == 503);
452 16
                http_SetStatus(hp, 503);
453
        }
454
455 3154
        if (hp->hd[HTTP_HDR_REASON].b == NULL ||
456 1577
            !Tlen(hp->hd[HTTP_HDR_REASON])) {
457 2
                http_SetH(hp, HTTP_HDR_REASON,
458 2
                    http_Status2Reason(hp->status, NULL));
459
        }
460
461 1577
        htc->body_status = http1_body_status(hp, htc, 0);
462
463 1577
        return (retval);
464
}
465
466
/*--------------------------------------------------------------------*/
467
468
static unsigned
469 34872
http1_WrTxt(const struct worker *wrk, const txt *hh, const char *suf)
470
{
471
        unsigned u;
472
473 34872
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
474 34872
        AN(wrk);
475 34872
        AN(hh);
476 34872
        AN(hh->b);
477 34872
        AN(hh->e);
478 34872
        u = V1L_Write(wrk, hh->b, hh->e - hh->b);
479 34872
        if (suf != NULL)
480 34872
                u += V1L_Write(wrk, suf, -1);
481 34872
        return (u);
482
}
483
484
unsigned
485 3712
HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf)
486
{
487
        unsigned u, l;
488
489 3712
        assert(hf == HTTP1_Req || hf == HTTP1_Resp);
490 3712
        AN(hp->hd[hf[0]].b);
491 3712
        AN(hp->hd[hf[1]].b);
492 3712
        AN(hp->hd[hf[2]].b);
493 3712
        l = http1_WrTxt(w, &hp->hd[hf[0]], " ");
494 3712
        l += http1_WrTxt(w, &hp->hd[hf[1]], " ");
495 3712
        l += http1_WrTxt(w, &hp->hd[hf[2]], "\r\n");
496
497 27448
        for (u = HTTP_HDR_FIRST; u < hp->nhd; u++)
498 23736
                l += http1_WrTxt(w, &hp->hd[u], "\r\n");
499 3712
        l += V1L_Write(w, "\r\n", -1);
500 3712
        return (l);
501
}