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
 * Until we see the magic marker, we have to keep the rxbuf NUL terminated
41
 * because we use strchr(3) on it.
42
 *
43
 * We use this both for client and backend connections.
44
 */
45
46
#include "config.h"
47
48
#include "cache/cache_varnishd.h"
49
#include "cache/cache_transport.h"
50
51
#include "cache_http1.h"
52
53
#include "vct.h"
54
55
const int HTTP1_Req[3] = {
56
        HTTP_HDR_METHOD, HTTP_HDR_URL, HTTP_HDR_PROTO
57
};
58
59
const int HTTP1_Resp[3] = {
60
        HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_REASON
61
};
62
63
/*--------------------------------------------------------------------
64
 * Check if we have a complete HTTP request or response yet
65
 */
66
67
enum htc_status_e v_matchproto_(htc_complete_f)
68 7336
HTTP1_Complete(struct http_conn *htc)
69
{
70
        char *p;
71
        enum htc_status_e retval;
72
73 7336
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
74
75 7336
        assert(htc->rxbuf_e >= htc->rxbuf_b);
76 7336
        assert(htc->rxbuf_e <= htc->ws->r);
77
78 7336
        if (htc->rxbuf_e == htc->ws->r)
79 4
                return (HTC_S_OVERFLOW);                // No space for NUL
80 7332
        *htc->rxbuf_e = '\0';
81
82
        /* Skip any leading white space */
83 7334
        for (p = htc->rxbuf_b ; vct_islws(*p); p++)
84 2
                continue;
85 7332
        if (p == htc->rxbuf_e)
86 4067
                return (HTC_S_EMPTY);
87
88
        /* Do not return a partial H2 connection preface */
89 3265
        retval = H2_prism_complete(htc);
90 3265
        if (retval != HTC_S_JUNK)
91 106
                return (retval);
92
93
        /*
94
         * Here we just look for NL[CR]NL to see that reception
95
         * is completed.  More stringent validation happens later.
96
         */
97
        while (1) {
98 5901
                p = strchr(p, '\n');
99 5901
                if (p == NULL)
100 203
                        return (HTC_S_MORE);
101 5698
                p++;
102 5698
                if (*p == '\r')
103 2941
                        p++;
104 5698
                if (*p == '\n')
105 2956
                        break;
106 2742
        }
107 2956
        return (HTC_S_COMPLETE);
108
}
109
110
/*--------------------------------------------------------------------
111
 * Dissect the headers of the HTTP protocol message.
112
 * Detect conditionals (headers which start with '^[Ii][Ff]-')
113
 */
114
115
static uint16_t
116 2951
http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc,
117
    unsigned maxhdr)
118
{
119
        char *q, *r;
120
121 2951
        assert(p > htc->rxbuf_b);
122 2951
        assert(p <= htc->rxbuf_e);
123 2951
        hp->nhd = HTTP_HDR_FIRST;
124 2951
        hp->conds = 0;
125 2951
        r = NULL;               /* For FlexeLint */
126 5454
        for (; p < htc->rxbuf_e; p = r) {
127
128
                /* Find end of next header */
129 5454
                q = r = p;
130 5454
                if (vct_iscrlf(p))
131
                        break;
132 57739
                while (r < htc->rxbuf_e) {
133 55218
                        if (!vct_isctl(*r) || vct_issp(*r)) {
134 52696
                                r++;
135 52696
                                continue;
136
                        }
137 2522
                        if (!vct_iscrlf(r)) {
138 4
                                VSLb(hp->vsl, SLT_BogoHeader,
139 4
                                    "Header has ctrl char 0x%02x", *r);
140 4
                                return (400);
141
                        }
142 2518
                        q = r;
143 2518
                        assert(r < htc->rxbuf_e);
144 2518
                        r += vct_skipcrlf(r);
145 2518
                        if (r >= htc->rxbuf_e)
146 0
                                break;
147 2518
                        if (vct_iscrlf(r))
148
                                break;
149
                        /* If line does not continue: got it. */
150 759
                        if (!vct_issp(*r))
151 754
                                break;
152
153
                        /* Clear line continuation LWS to spaces */
154 20
                        while (vct_islws(*q))
155 10
                                *q++ = ' ';
156
                }
157
158 2515
                if (q - p > maxhdr) {
159 4
                        VSLb(hp->vsl, SLT_BogoHeader, "Header too long: %.*s",
160 4
                            (int)(q - p > 20 ? 20 : q - p), p);
161 4
                        return (400);
162
                }
163
164
                /* Empty header = end of headers */
165 2511
                if (p == q)
166 2
                        break;
167
168 2509
                if (vct_islws(*p)) {
169 4
                        VSLb(hp->vsl, SLT_BogoHeader,
170
                            "1st header has white space: %.*s",
171 4
                            (int)(q - p > 20 ? 20 : q - p), p);
172 2
                        return (400);
173
                }
174
175 2568
                if ((p[0] == 'i' || p[0] == 'I') &&
176 122
                    (p[1] == 'f' || p[1] == 'F') &&
177 53
                    p[2] == '-')
178 53
                        hp->conds = 1;
179
180 5026
                while (q > p && vct_issp(q[-1]))
181 12
                        q--;
182 2507
                *q = '\0';
183
184 2507
                if (strchr(p, ':') == NULL) {
185 6
                        VSLb(hp->vsl, SLT_BogoHeader, "Header without ':' %.*s",
186 6
                            (int)(q - p > 20 ? 20 : q - p), p);
187 3
                        return (400);
188
                }
189
190 2504
                if (hp->nhd < hp->shd) {
191 2504
                        hp->hdf[hp->nhd] = 0;
192 2504
                        hp->hd[hp->nhd].b = p;
193 2504
                        hp->hd[hp->nhd].e = q;
194 2504
                        hp->nhd++;
195
                } else {
196 0
                        VSLb(hp->vsl, SLT_BogoHeader, "Too many headers: %.*s",
197 0
                            (int)(q - p > 20 ? 20 : q - p), p);
198 0
                        return (400);
199
                }
200
201 29488
                for (; p < q; p++) {
202 29488
                        if (vct_islws(*p)) {
203 2
                                VSLb(hp->vsl, SLT_BogoHeader,
204
                                    "Space in header '%.*s'",
205 1
                                    (int)Tlen(hp->hd[hp->nhd - 1]),
206 1
                                    hp->hd[hp->nhd - 1].b);
207 1
                                return (400);
208
                        }
209 29487
                        if (*p == ':')
210 2503
                                break;
211
                }
212
        }
213 2937
        if (p < htc->rxbuf_e)
214 2937
                p += vct_skipcrlf(p);
215 2937
        HTC_RxPipeline(htc, p);
216 2937
        htc->rxbuf_e = p;
217 2937
        return (0);
218
}
219
220
/*--------------------------------------------------------------------
221
 * Deal with first line of HTTP protocol message.
222
 */
223
224
static uint16_t
225 2956
http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
226
    unsigned maxhdr)
227
{
228
        char *p;
229
        int i;
230
231 2956
        assert(hf == HTTP1_Req || hf == HTTP1_Resp);
232 2956
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
233 2956
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
234 2956
        assert(htc->rxbuf_e >= htc->rxbuf_b);
235
236 2956
        AZ(hp->hd[hf[0]].b);
237 2956
        AZ(hp->hd[hf[1]].b);
238 2956
        AZ(hp->hd[hf[2]].b);
239
240
        /* Skip leading LWS */
241 2956
        for (p = htc->rxbuf_b ; vct_islws(*p); p++)
242 0
                continue;
243 2956
        hp->hd[hf[0]].b = p;
244
245
        /* First field cannot contain SP or CTL */
246 18382
        for (; !vct_issp(*p); p++) {
247 15429
                if (vct_isctl(*p))
248 3
                        return (400);
249
        }
250 2953
        hp->hd[hf[0]].e = p;
251 2953
        assert(Tlen(hp->hd[hf[0]]));
252 2953
        *p++ = '\0';
253
254
        /* Skip SP */
255 2956
        for (; vct_issp(*p); p++) {
256 3
                if (vct_isctl(*p))
257 0
                        return (400);
258
        }
259 2953
        hp->hd[hf[1]].b = p;
260
261
        /* Second field cannot contain LWS or CTL */
262 12688
        for (; !vct_islws(*p); p++) {
263 9735
                if (vct_isctl(*p))
264 0
                        return (400);
265
        }
266 2953
        hp->hd[hf[1]].e = p;
267 2953
        if (!Tlen(hp->hd[hf[1]]))
268 1
                return (400);
269 2952
        *p++ = '\0';
270
271
        /* Skip SP */
272 2952
        for (; vct_issp(*p); p++) {
273 0
                if (vct_isctl(*p))
274 0
                        return (400);
275
        }
276 2952
        hp->hd[hf[2]].b = p;
277
278
        /* Third field is optional and cannot contain CTL except TAB */
279 18867
        for (; !vct_iscrlf(p); p++) {
280 15916
                if (vct_isctl(*p) && !vct_issp(*p)) {
281 1
                        hp->hd[hf[2]].b = NULL;
282 1
                        return (400);
283
                }
284
        }
285 2951
        hp->hd[hf[2]].e = p;
286
287
        /* Skip CRLF */
288 2951
        i = vct_skipcrlf(p);
289 2951
        *p = '\0';
290 2951
        p += i;
291
292 2951
        http_Proto(hp);
293
294 2951
        return (http1_dissect_hdrs(hp, p, htc, maxhdr));
295
}
296
297
/*--------------------------------------------------------------------*/
298
299
static enum body_status
300 2936
http1_body_status(const struct http *hp, struct http_conn *htc, int request)
301
{
302
        ssize_t cl;
303
        const char *b;
304
305 2936
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
306 2936
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
307
308 2936
        htc->content_length = -1;
309
310 2936
        cl = http_GetContentLength(hp);
311 2936
        if (cl == -2)
312 3
                return (BS_ERROR);
313 2933
        if (http_GetHdr(hp, H_Transfer_Encoding, &b)) {
314 50
                if (strcasecmp(b, "chunked"))
315 2
                        return (BS_ERROR);
316 48
                if (cl != -1) {
317
                        /*
318
                         * RFC7230 3.3.3 allows more lenient handling
319
                         * but we're going to be strict.
320
                         */
321 2
                        return (BS_ERROR);
322
                }
323 46
                return (BS_CHUNKED);
324
        }
325 2882
        if (cl >= 0) {
326 1248
                htc->content_length = cl;
327 1248
                return (cl == 0 ? BS_NONE : BS_LENGTH);
328
        }
329
330 1634
        if (hp->protover == 11 && request)
331 1592
                return (BS_NONE);
332
333 42
        if (http_HdrIs(hp, H_Connection, "keep-alive")) {
334
                /*
335
                 * Keep alive with neither TE=Chunked or C-Len is impossible.
336
                 * We assume a zero length body.
337
                 */
338 1
                return (BS_NONE);
339
        }
340
341
        /*
342
         * Fall back to EOF transfer.
343
         */
344 41
        return (BS_EOF);
345
}
346
347
/*--------------------------------------------------------------------*/
348
349
uint16_t
350 1669
HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)
351
{
352
        uint16_t retval;
353
        const char *p;
354 1669
        const char *b = NULL, *e;
355
356 1669
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
357 1669
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
358
359 1669
        retval = http1_splitline(hp, htc,
360 1669
            HTTP1_Req, cache_param->http_req_hdr_len);
361 1669
        if (retval != 0)
362 13
                return (retval);
363
364 1656
        if (hp->protover < 10 || hp->protover > 11)
365 5
                return (400);
366
367 1651
        if (http_CountHdr(hp, H_Host) > 1)
368 1
                return (400);
369
370 1650
        if (http_CountHdr(hp, H_Content_Length) > 1)
371 1
                return (400);
372
373
        /* RFC2616, section 5.2, point 1 */
374 1649
        if (!strncasecmp(hp->hd[HTTP_HDR_URL].b, "http://", 7))
375 3
                b = hp->hd[HTTP_HDR_URL].b + 7;
376 1647
        else if (FEATURE(FEATURE_HTTPS_SCHEME) &&
377 1
            !strncasecmp(hp->hd[HTTP_HDR_URL].b, "https://", 8))
378 1
                b = hp->hd[HTTP_HDR_URL].b + 8;
379 1649
        if (b) {
380 4
                e = strchr(b, '/');
381 4
                if (e) {
382 4
                        http_Unset(hp, H_Host);
383 4
                        http_PrintfHeader(hp, "Host: %.*s", (int)(e - b), b);
384 4
                        hp->hd[HTTP_HDR_URL].b = e;
385
                }
386
        }
387
388 1649
        htc->body_status = http1_body_status(hp, htc, 1);
389 1648
        if (htc->body_status == BS_ERROR)
390 3
                return (400);
391
392 1645
        p = http_GetMethod(hp);
393 1646
        AN(p);
394
395 1646
        if (htc->body_status == BS_EOF) {
396 7
                assert(hp->protover == 10);
397
                /* RFC1945 8.3 p32 and D.1.1 p58 */
398 7
                if (!strcasecmp(p, "post") || !strcasecmp(p, "put"))
399 2
                        return (400);
400 5
                htc->body_status = BS_NONE;
401
        }
402
403
        /* HEAD with a body is a hard error */
404 1644
        if (htc->body_status != BS_NONE && !strcasecmp(p, "head"))
405 0
                return (400);
406
407 1644
        return (retval);
408
}
409
410
/*--------------------------------------------------------------------*/
411
412
uint16_t
413 1287
HTTP1_DissectResponse(struct http_conn *htc, struct http *hp,
414
    const struct http *rhttp)
415
{
416 1287
        uint16_t retval = 0;
417
        const char *p;
418
419 1287
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
420 1287
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
421 1287
        CHECK_OBJ_NOTNULL(rhttp, HTTP_MAGIC);
422
423 1287
        if (http1_splitline(hp, htc,
424 1287
            HTTP1_Resp, cache_param->http_resp_hdr_len))
425 6
                retval = 503;
426
427 1287
        if (retval == 0 && hp->protover < 10)
428 0
                retval = 503;
429
430 1287
        if (retval == 0 && hp->protover > rhttp->protover)
431 1
                http_SetH(hp, HTTP_HDR_PROTO, rhttp->hd[HTTP_HDR_PROTO].b);
432
433 1287
        if (retval == 0 && Tlen(hp->hd[HTTP_HDR_STATUS]) != 3)
434 3
                retval = 503;
435
436 1287
        if (retval == 0) {
437 1278
                p = hp->hd[HTTP_HDR_STATUS].b;
438
439 2553
                if (p[0] >= '1' && p[0] <= '9' &&
440 3822
                    p[1] >= '0' && p[1] <= '9' &&
441 2545
                    p[2] >= '0' && p[2] <= '9')
442 3813
                        hp->status =
443 3813
                            100 * (p[0] - '0') + 10 * (p[1] - '0') + p[2] - '0';
444
                else
445 7
                        retval = 503;
446
        }
447
448 1287
        if (retval != 0) {
449 32
                VSLb(hp->vsl, SLT_HttpGarbage, "%.*s",
450 16
                    (int)(htc->rxbuf_e - htc->rxbuf_b), htc->rxbuf_b);
451 16
                assert(retval >= 100 && retval <= 999);
452 16
                assert(retval == 503);
453 16
                http_SetStatus(hp, 503);
454
        }
455
456 2574
        if (hp->hd[HTTP_HDR_REASON].b == NULL ||
457 1287
            !Tlen(hp->hd[HTTP_HDR_REASON])) {
458 2
                http_SetH(hp, HTTP_HDR_REASON,
459 2
                    http_Status2Reason(hp->status, NULL));
460
        }
461
462 1287
        htc->body_status = http1_body_status(hp, htc, 0);
463
464 1287
        return (retval);
465
}
466
467
/*--------------------------------------------------------------------*/
468
469
static unsigned
470 27550
http1_WrTxt(const struct worker *wrk, const txt *hh, const char *suf)
471
{
472
        unsigned u;
473
474 27550
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
475 27550
        AN(wrk);
476 27550
        AN(hh);
477 27550
        AN(hh->b);
478 27550
        AN(hh->e);
479 27550
        u = V1L_Write(wrk, hh->b, hh->e - hh->b);
480 27542
        if (suf != NULL)
481 27542
                u += V1L_Write(wrk, suf, -1);
482 27546
        return (u);
483
}
484
485
unsigned
486 2935
HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf)
487
{
488
        unsigned u, l;
489
490 2935
        assert(hf == HTTP1_Req || hf == HTTP1_Resp);
491 2935
        AN(hp->hd[hf[0]].b);
492 2935
        AN(hp->hd[hf[1]].b);
493 2935
        AN(hp->hd[hf[2]].b);
494 2935
        l = http1_WrTxt(w, &hp->hd[hf[0]], " ");
495 2937
        l += http1_WrTxt(w, &hp->hd[hf[1]], " ");
496 2935
        l += http1_WrTxt(w, &hp->hd[hf[2]], "\r\n");
497
498 21676
        for (u = HTTP_HDR_FIRST; u < hp->nhd; u++)
499 18741
                l += http1_WrTxt(w, &hp->hd[u], "\r\n");
500 2935
        l += V1L_Write(w, "\r\n", -1);
501 2935
        return (l);
502
}