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