~ubuntu-branches/ubuntu/lucid/varnish/lucid-updates

« back to all changes in this revision

Viewing changes to bin/varnishd/cache_center.c

  • Committer: Bazaar Package Importer
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2010-03-24 13:26:08 UTC
  • mfrom: (0.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20100324132608-4uzkavctn26bdwyi
Tags: 2.1.0-1
* New upstream version
* Fix small error in man/vcl.7so

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*-
2
2
 * Copyright (c) 2006 Verdens Gang AS
3
 
 * Copyright (c) 2006-2008 Linpro AS
 
3
 * Copyright (c) 2006-2010 Redpill Linpro AS
4
4
 * All rights reserved.
5
5
 *
6
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
26
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
27
 * SUCH DAMAGE.
28
28
 *
29
 
 * $Id: cache_center.c 4398 2009-12-16 08:50:49Z tfheen $
30
 
 *
31
29
 * This file contains the central state machine for pushing requests.
32
30
 *
33
31
 * We cannot just use direct calls because it is possible to kick a
59
57
 
60
58
#include "config.h"
61
59
 
 
60
#include "svnid.h"
 
61
SVNID("$Id: cache_center.c 4605 2010-03-09 11:27:08Z phk $")
 
62
 
62
63
#include <stdio.h>
63
64
#include <errno.h>
64
65
#include <math.h>
76
77
#include "cli_priv.h"
77
78
#include "cache.h"
78
79
#include "hash_slinger.h"
 
80
#include "stevedore.h"
 
81
#include "vsha256.h"
79
82
 
80
83
static unsigned xids;
81
84
 
82
85
/*--------------------------------------------------------------------
83
86
 * WAIT
84
 
 * Wait until we have a full request in our htc.
 
87
 * Wait (briefly) until we have a full request in our htc.
85
88
 */
86
89
 
87
90
static int
96
99
        assert(sp->xid == 0);
97
100
 
98
101
        i = HTC_Complete(sp->htc);
99
 
        while (i == 0) {
100
 
                if (params->session_linger > 0) {
101
 
                        pfd[0].fd = sp->fd;
102
 
                        pfd[0].events = POLLIN;
103
 
                        pfd[0].revents = 0;
104
 
                        i = poll(pfd, 1, params->session_linger);
105
 
                        if (i == 0) {
106
 
                                WSL(sp->wrk, SLT_Debug, sp->fd, "herding");
107
 
                                VSL_stats->sess_herd++;
108
 
                                SES_Charge(sp);
109
 
                                sp->wrk = NULL;
110
 
                                vca_return_session(sp);
111
 
                                return (1);
112
 
                        }
113
 
                }
114
 
                i = HTC_Rx(sp->htc);
 
102
        if (i == 0 && params->session_linger > 0) {
 
103
                pfd[0].fd = sp->fd;
 
104
                pfd[0].events = POLLIN;
 
105
                pfd[0].revents = 0;
 
106
                i = poll(pfd, 1, params->session_linger);
 
107
                if (i)
 
108
                        i = HTC_Rx(sp->htc);
 
109
        }
 
110
        if (i == 0) {
 
111
                WSL(sp->wrk, SLT_Debug, sp->fd, "herding");
 
112
                sp->wrk->stats.sess_herd++;
 
113
                SES_Charge(sp);
 
114
                sp->wrk = NULL;
 
115
                vca_return_session(sp);
 
116
                return (1);
115
117
        }
116
118
        if (i == 1) {
117
119
                sp->step = STP_START;
118
 
        } else {
119
 
                if (i == -2)
120
 
                        vca_close_session(sp, "overflow");
121
 
                else if (i == -1 && Tlen(sp->htc->rxbuf) == 0 &&
122
 
                    (errno == 0 || errno == ECONNRESET))
123
 
                        vca_close_session(sp, "EOF");
124
 
                else 
125
 
                        vca_close_session(sp, "error");
126
 
                sp->step = STP_DONE;
127
 
        }
 
120
                return (0);
 
121
        }
 
122
        if (i == -2) {
 
123
                vca_close_session(sp, "overflow");
 
124
                return (0);
 
125
        }
 
126
        if (i == -1 && Tlen(sp->htc->rxbuf) == 0 &&
 
127
            (errno == 0 || errno == ECONNRESET))
 
128
                vca_close_session(sp, "EOF");
 
129
        else
 
130
                vca_close_session(sp, "error");
 
131
        sp->step = STP_DONE;
128
132
        return (0);
129
133
}
130
134
 
174
178
        CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
175
179
        CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
176
180
 
177
 
        AZ(sp->bereq);
178
 
 
179
181
        sp->t_resp = TIM_real();
180
 
        if (sp->obj->objhead != NULL) {
 
182
        if (sp->obj->objcore != NULL) {
 
183
                if ((sp->t_resp - sp->obj->last_lru) > params->lru_timeout &&
 
184
                    EXP_Touch(sp->obj))
 
185
                        sp->obj->last_lru = sp->t_resp; /* XXX: locking ? */
181
186
                sp->obj->last_use = sp->t_resp; /* XXX: locking ? */
182
 
                EXP_Touch(sp->obj, sp->t_resp);
183
187
        }
 
188
        sp->wrk->resp = sp->wrk->http[2];
 
189
        http_Setup(sp->wrk->resp, sp->wrk->ws);
184
190
        RES_BuildHttp(sp);
185
191
        VCL_deliver_method(sp);
186
192
        switch (sp->handling) {
198
204
 
199
205
        RES_WriteObj(sp);
200
206
        AZ(sp->wrk->wfd);
201
 
        HSH_Deref(&sp->obj);
 
207
        HSH_Deref(sp->wrk, &sp->obj);
 
208
        sp->wrk->resp = NULL;
202
209
        sp->step = STP_DONE;
203
210
        return (0);
204
211
}
224
231
 
225
232
        AZ(sp->obj);
226
233
        AZ(sp->vbe);
227
 
        AZ(sp->bereq);
228
234
        sp->director = NULL;
229
235
        sp->restarts = 0;
230
236
 
253
259
        WSL_Flush(sp->wrk, 0);
254
260
 
255
261
        /* If we did an ESI include, don't mess up our state */
256
 
        if (sp->esis > 0)
 
262
        if (sp->esis > 0) {
 
263
                SES_Charge(sp);
257
264
                return (1);
 
265
        }
258
266
 
259
267
        sp->t_req = NAN;
260
268
 
261
269
        if (sp->fd >= 0 && sp->doclose != NULL) {
262
270
                /*
263
 
                 * This is an orderly close of the connection; ditch linger 
 
271
                 * This is an orderly close of the connection; ditch nolinger
264
272
                 * before we close, to get queued data transmitted.
265
273
                 */
266
 
                TCP_linger(sp->fd, 0);
 
274
                // XXX: not yet (void)TCP_linger(sp->fd, 0);
267
275
                vca_close_session(sp, sp->doclose);
268
276
        }
 
277
 
 
278
        SES_Charge(sp);
 
279
 
269
280
        if (sp->fd < 0) {
270
 
                SES_Charge(sp);
271
 
                VSL_stats->sess_closed++;
 
281
                sp->wrk->stats.sess_closed++;
272
282
                sp->wrk = NULL;
273
283
                SES_Delete(sp);
274
284
                return (1);
275
285
        }
276
286
 
 
287
        if (sp->wrk->stats.client_req >= params->wthread_stats_rate)
 
288
                WRK_SumStat(sp->wrk);
277
289
        /* Reset the workspace to the session-watermark */
278
290
        WS_Reset(sp->ws, sp->ws_ses);
279
291
 
280
292
        i = HTC_Reinit(sp->htc);
281
293
        if (i == 1) {
282
 
                VSL_stats->sess_pipeline++;
 
294
                sp->wrk->stats.sess_pipeline++;
283
295
                sp->step = STP_START;
284
296
                return (0);
285
297
        }
286
298
        if (Tlen(sp->htc->rxbuf)) {
287
 
                VSL_stats->sess_readahead++;
 
299
                sp->wrk->stats.sess_readahead++;
288
300
                sp->step = STP_WAIT;
289
301
                return (0);
290
302
        }
291
303
        if (params->session_linger > 0) {
292
 
                VSL_stats->sess_linger++;
 
304
                sp->wrk->stats.sess_linger++;
293
305
                sp->step = STP_WAIT;
294
306
                return (0);
295
307
        }
296
 
        VSL_stats->sess_herd++;
297
 
        SES_Charge(sp);
 
308
        sp->wrk->stats.sess_herd++;
298
309
        sp->wrk = NULL;
299
310
        vca_return_session(sp);
300
311
        return (1);
321
332
        char date[40];
322
333
 
323
334
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
324
 
        AZ(sp->bereq);
325
335
 
326
336
        w = sp->wrk;
327
337
        if (sp->obj == NULL) {
328
 
                HSH_Prealloc(sp, 1);
329
 
                sp->obj = sp->wrk->nobj;
 
338
                HSH_Prealloc(sp);
 
339
                sp->wrk->cacheable = 0;
 
340
                /* XXX: 1024 is a pure guess */
 
341
                sp->obj = STV_NewObject(sp, 1024, 0, params->http_headers);
330
342
                sp->obj->xid = sp->xid;
331
343
                sp->obj->entered = sp->t_req;
332
 
                sp->wrk->nobj = NULL;
333
344
        } else {
334
345
                /* XXX: Null the headers ? */
335
346
        }
353
364
                    http_StatusMessage(sp->err_code));
354
365
        VCL_error_method(sp);
355
366
 
356
 
        if (sp->handling == VCL_RET_RESTART && sp->restarts <  params->max_restarts) {
 
367
        if (sp->handling == VCL_RET_RESTART &&
 
368
            sp->restarts <  params->max_restarts) {
357
369
                HSH_Drop(sp);
358
370
                sp->director = NULL;
359
371
                sp->restarts++;
361
373
                return (0);
362
374
        } else if (sp->handling == VCL_RET_RESTART)
363
375
                sp->handling = VCL_RET_DELIVER;
364
 
                  
 
376
 
365
377
 
366
378
        /* We always close when we take this path */
367
379
        sp->doclose = "error";
370
382
        assert(sp->handling == VCL_RET_DELIVER);
371
383
        sp->err_code = 0;
372
384
        sp->err_reason = NULL;
 
385
        sp->wrk->bereq = NULL;
373
386
        sp->step = STP_DELIVER;
374
387
        return (0);
375
388
}
385
398
DOT     ]
386
399
DOT     vcl_fetch [
387
400
DOT             shape=record
388
 
DOT             label="vcl_fetch()|req.\nobj.\nbereq."
 
401
DOT             label="vcl_fetch()|req.\nobj.\nbereq.\nberesp."
389
402
DOT     ]
390
403
DOT     fetch -> vcl_fetch [style=bold,color=blue,weight=2]
391
404
DOT     fetch_pass [
408
421
cnt_fetch(struct sess *sp)
409
422
{
410
423
        int i;
 
424
        struct http *hp, *hp2;
 
425
        char *b;
 
426
        unsigned handling, l, nhttp;
 
427
        int varyl = 0;
 
428
        struct vsb *vary = NULL;
411
429
 
412
430
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
413
431
        CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
414
432
 
415
 
        AN(sp->bereq);
416
 
        AN(sp->director);
417
 
        AZ(sp->vbe);
418
 
        i = Fetch(sp);
419
 
        AZ(sp->wrk->wfd);
420
 
        AZ(sp->vbe);
421
 
        AN(sp->director);
 
433
        AN(sp->director);
 
434
        AZ(sp->vbe);
 
435
 
 
436
        /* sp->wrk->http[0] is (still) bereq */
 
437
        sp->wrk->beresp = sp->wrk->http[1];
 
438
        http_Setup(sp->wrk->beresp, sp->wrk->ws);
 
439
 
 
440
        i = FetchHdr(sp);
 
441
 
 
442
        /*
 
443
         * Save a copy before it might get mangled in VCL.  When it comes to
 
444
         * dealing with the body, we want to see the unadultered headers.
 
445
         */
 
446
        sp->wrk->beresp1 = sp->wrk->http[2];
 
447
        *sp->wrk->beresp1 = *sp->wrk->beresp;
422
448
 
423
449
        if (i) {
 
450
                if (sp->objcore != NULL) {
 
451
                        CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
 
452
                        CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
 
453
                        HSH_DerefObjCore(sp);
 
454
                        AZ(sp->objhead);
 
455
                        AZ(sp->objcore);
 
456
                }
 
457
                AZ(sp->obj);
 
458
                sp->wrk->bereq = NULL;
 
459
                sp->wrk->beresp = NULL;
 
460
                sp->wrk->beresp1 = NULL;
424
461
                sp->err_code = 503;
425
462
                sp->step = STP_ERROR;
426
 
                VBE_free_bereq(&sp->bereq);
427
 
                HSH_Drop(sp);
428
 
                AZ(sp->obj);
429
463
                return (0);
430
464
        }
431
465
 
432
 
        RFC2616_cache_policy(sp, sp->obj->http);        /* XXX -> VCL */
433
 
 
434
 
        sp->err_code = http_GetStatus(sp->obj->http);
 
466
        sp->err_code = http_GetStatus(sp->wrk->beresp);
 
467
 
 
468
        /*
 
469
         * Initial cacheability determination per [RFC2616, 13.4]
 
470
         * We do not support ranges yet, so 206 is out.
 
471
         */
 
472
        switch (sp->err_code) {
 
473
        case 200: /* OK */
 
474
        case 203: /* Non-Authoritative Information */
 
475
        case 300: /* Multiple Choices */
 
476
        case 301: /* Moved Permanently */
 
477
        case 302: /* Moved Temporarily */
 
478
        case 410: /* Gone */
 
479
        case 404: /* Not Found */
 
480
                sp->wrk->cacheable = 1;
 
481
                break;
 
482
        default:
 
483
                sp->wrk->cacheable = 0;
 
484
                break;
 
485
        }
 
486
 
 
487
        sp->wrk->entered = TIM_real();
 
488
        sp->wrk->age = 0;
 
489
        sp->wrk->ttl = RFC2616_Ttl(sp);
 
490
 
 
491
        if (sp->objcore == NULL)
 
492
                sp->wrk->cacheable = 0;
 
493
 
 
494
        sp->wrk->do_esi = 0;
 
495
        sp->wrk->grace = NAN;
 
496
 
435
497
        VCL_fetch_method(sp);
436
498
 
437
 
        VBE_free_bereq(&sp->bereq);
438
 
 
439
 
        switch (sp->handling) {
 
499
        /*
 
500
         * When we fetch the body, we may hit the LRU cleanup and that
 
501
         * will overwrite sp->handling, so we have to save our plans
 
502
         * here.
 
503
         */
 
504
        handling = sp->handling;
 
505
 
 
506
        if (sp->objcore == NULL) {
 
507
                /* This is a pass from vcl_recv */
 
508
                AZ(sp->objhead);
 
509
                sp->wrk->cacheable = 0;
 
510
        } else if (!sp->wrk->cacheable) {
 
511
                if (sp->objhead != NULL)
 
512
                        HSH_DerefObjCore(sp);
 
513
        }
 
514
 
 
515
        /*
 
516
         * At this point we are either committed to flesh out the busy
 
517
         * object we have in the hash or we have let go of it, if we ever
 
518
         * had one.
 
519
         */
 
520
 
 
521
        if (sp->wrk->cacheable) {
 
522
                CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
 
523
                CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
 
524
                vary = VRY_Create(sp, sp->wrk->beresp);
 
525
                if (vary != NULL) {
 
526
                        varyl = vsb_len(vary);
 
527
                        assert(varyl > 0);
 
528
                }
 
529
        } else {
 
530
                AZ(sp->objhead);
 
531
                AZ(sp->objcore);
 
532
        }
 
533
 
 
534
        l = http_EstimateWS(sp->wrk->beresp, HTTPH_A_INS, &nhttp);
 
535
 
 
536
        if (vary != NULL)
 
537
                l += varyl;
 
538
 
 
539
        /* Space for producing a Content-Length: header */
 
540
        l += 30;
 
541
 
 
542
        /*
 
543
         * XXX: If we have a Length: header, we should allocate the body
 
544
         * XXX: also.
 
545
         */
 
546
 
 
547
        sp->obj = STV_NewObject(sp, l, sp->wrk->ttl, nhttp);
 
548
 
 
549
        if (sp->objhead != NULL) {
 
550
                CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
 
551
                CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
 
552
                sp->objcore->obj = sp->obj;
 
553
                sp->obj->objcore = sp->objcore;
 
554
                sp->objcore->objhead = sp->objhead;
 
555
                sp->objhead = NULL;     /* refcnt follows pointer. */
 
556
                sp->objcore = NULL;     /* refcnt follows pointer. */
 
557
                BAN_NewObj(sp->obj);
 
558
        }
 
559
 
 
560
        if (vary != NULL) {
 
561
                sp->obj->vary =
 
562
                    (void *)WS_Alloc(sp->obj->http->ws, varyl);
 
563
                AN(sp->obj->vary);
 
564
                memcpy(sp->obj->vary, vsb_data(vary), varyl);
 
565
                vsb_delete(vary);
 
566
                vary = NULL;
 
567
        }
 
568
 
 
569
        sp->obj->xid = sp->xid;
 
570
        sp->obj->response = sp->err_code;
 
571
        sp->obj->cacheable = sp->wrk->cacheable;
 
572
        sp->obj->ttl = sp->wrk->ttl;
 
573
        sp->obj->grace = sp->wrk->grace;
 
574
        if (sp->obj->ttl == 0. && sp->obj->grace == 0.)
 
575
                sp->obj->cacheable = 0;
 
576
        sp->obj->age = sp->wrk->age;
 
577
        sp->obj->entered = sp->wrk->entered;
 
578
        WS_Assert(sp->obj->ws_o);
 
579
 
 
580
        /* Filter into object */
 
581
        hp = sp->wrk->beresp;
 
582
        hp2 = sp->obj->http;
 
583
 
 
584
        hp2->logtag = HTTP_Obj;
 
585
        http_CopyResp(hp2, hp);
 
586
        http_FilterFields(sp->wrk, sp->fd, hp2, hp, HTTPH_A_INS);
 
587
        http_CopyHome(sp->wrk, sp->fd, hp2);
 
588
 
 
589
        if (http_GetHdr(hp, H_Last_Modified, &b))
 
590
                sp->obj->last_modified = TIM_parse(b);
 
591
 
 
592
        i = FetchBody(sp);
 
593
        AZ(sp->wrk->wfd);
 
594
        AZ(sp->vbe);
 
595
        AN(sp->director);
 
596
 
 
597
        if (i) {
 
598
                HSH_Drop(sp);
 
599
                AZ(sp->obj);
 
600
                sp->wrk->bereq = NULL;
 
601
                sp->wrk->beresp = NULL;
 
602
                sp->wrk->beresp1 = NULL;
 
603
                sp->err_code = 503;
 
604
                sp->step = STP_ERROR;
 
605
                return (0);
 
606
        }
 
607
 
 
608
        if (sp->wrk->cacheable)
 
609
                HSH_Object(sp);
 
610
 
 
611
        if (sp->wrk->do_esi)
 
612
                ESI_Parse(sp);
 
613
 
 
614
        switch (handling) {
440
615
        case VCL_RET_RESTART:
441
616
                HSH_Drop(sp);
442
617
                sp->director = NULL;
443
618
                sp->restarts++;
 
619
                sp->wrk->bereq = NULL;
 
620
                sp->wrk->beresp = NULL;
 
621
                sp->wrk->beresp1 = NULL;
444
622
                sp->step = STP_RECV;
445
623
                return (0);
446
624
        case VCL_RET_PASS:
447
 
                sp->obj->pass = 1;
 
625
                if (sp->obj->objcore != NULL)
 
626
                        sp->obj->objcore->flags |= OC_F_PASS;
448
627
                if (sp->obj->ttl - sp->t_req < params->default_ttl)
449
628
                        sp->obj->ttl = sp->t_req + params->default_ttl;
450
629
                break;
451
630
        case VCL_RET_DELIVER:
452
631
                break;
453
632
        case VCL_RET_ERROR:
 
633
                HSH_Drop(sp);
 
634
                sp->wrk->bereq = NULL;
 
635
                sp->wrk->beresp = NULL;
 
636
                sp->wrk->beresp1 = NULL;
454
637
                sp->step = STP_ERROR;
455
 
                HSH_Drop(sp);
456
638
                return (0);
457
639
        default:
458
640
                WRONG("Illegal action in vcl_fetch{}");
459
641
        }
460
642
 
461
643
        sp->obj->cacheable = 1;
462
 
        if (sp->obj->objhead != NULL) {
463
 
                VRY_Create(sp);
 
644
        if (sp->wrk->cacheable) {
464
645
                EXP_Insert(sp->obj);
465
646
                AN(sp->obj->ban);
466
647
                HSH_Unbusy(sp);
467
648
        }
468
649
        sp->acct_req.fetch++;
 
650
        sp->wrk->bereq = NULL;
 
651
        sp->wrk->beresp = NULL;
 
652
        sp->wrk->beresp1 = NULL;
469
653
        sp->step = STP_DELIVER;
470
654
        return (0);
471
655
}
495
679
        HTC_Init(sp->htc, sp->ws, sp->fd);
496
680
        sp->wrk->lastused = sp->t_open;
497
681
        sp->acct_req.sess++;
498
 
        SES_RefSrcAddr(sp);
499
682
 
500
683
        sp->step = STP_WAIT;
501
684
        return (0);
527
710
        CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
528
711
        CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
529
712
 
530
 
        assert(!sp->obj->pass);
 
713
        assert(!(sp->obj->objcore->flags & OC_F_PASS));
531
714
 
532
715
        VCL_hit_method(sp);
533
716
 
534
717
        if (sp->handling == VCL_RET_DELIVER) {
535
718
                /* Dispose of any body part of the request */
536
 
                FetchReqBody(sp);
 
719
                (void)FetchReqBody(sp);
 
720
                sp->wrk->bereq = NULL;
537
721
                sp->step = STP_DELIVER;
538
722
                return (0);
539
723
        }
540
724
 
541
725
        /* Drop our object, we won't need it */
542
 
        HSH_Deref(&sp->obj);
 
726
        HSH_Deref(sp->wrk, &sp->obj);
 
727
        sp->objcore = NULL;
 
728
        AZ(sp->objhead);
543
729
 
544
730
        switch(sp->handling) {
545
731
        case VCL_RET_PASS:
589
775
static int
590
776
cnt_lookup(struct sess *sp)
591
777
{
 
778
        struct objcore *oc;
592
779
        struct object *o;
 
780
        struct objhead *oh;
593
781
 
594
782
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
595
783
        CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
596
784
 
597
 
        if (sp->obj == NULL) {
598
 
                HSH_Prepare(sp, sp->vcl->nhashcount);
599
 
                VCL_hash_method(sp);
600
 
                assert(sp->handling == VCL_RET_HASH);
601
 
        }
602
 
 
603
 
        o = HSH_Lookup(sp);
604
 
 
605
 
        if (o == NULL) {
 
785
 
 
786
        oc = HSH_Lookup(sp, &oh);
 
787
 
 
788
        if (oc == NULL) {
606
789
                /*
607
790
                 * We lost the session to a busy object, disembark the
608
791
                 * worker thread.   The hash code to restart the session,
609
792
                 * still in STP_LOOKUP, later when the busy object isn't.
 
793
                 * NB:  Do not access sp any more !
610
794
                 */
611
795
                return (1);
612
796
        }
613
797
 
614
 
        sp->obj = o;
 
798
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
 
799
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
615
800
 
616
801
        /* If we inserted a new object it's a miss */
617
 
        if (sp->obj->busy) {
618
 
                VSL_stats->cache_miss++;
 
802
        if (oc->flags & OC_F_BUSY) {
 
803
                sp->wrk->stats.cache_miss++;
 
804
 
 
805
                AZ(oc->obj);
 
806
                sp->objhead = oh;
 
807
                sp->objcore = oc;
619
808
                sp->step = STP_MISS;
620
809
                return (0);
621
810
        }
622
811
 
623
 
        if (sp->obj->pass) {
624
 
                VSL_stats->cache_hitpass++;
 
812
        o = oc->obj;
 
813
        CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 
814
        sp->obj = o;
 
815
 
 
816
        if (oc->flags & OC_F_PASS) {
 
817
                sp->wrk->stats.cache_hitpass++;
625
818
                WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
626
 
                HSH_Deref(&sp->obj);
 
819
                HSH_Deref(sp->wrk, &sp->obj);
 
820
                sp->objcore = NULL;
 
821
                sp->objhead = NULL;
627
822
                sp->step = STP_PASS;
628
823
                return (0);
629
824
        }
630
825
 
631
 
        VSL_stats->cache_hit++;
 
826
        sp->wrk->stats.cache_hit++;
632
827
        WSP(sp, SLT_Hit, "%u", sp->obj->xid);
633
828
        sp->step = STP_HIT;
634
829
        return (0);
662
857
{
663
858
 
664
859
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
665
 
        CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
666
860
        CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
667
861
 
 
862
        AZ(sp->obj);
 
863
        AN(sp->objcore);
 
864
        AN(sp->objhead);
 
865
        WS_Reset(sp->wrk->ws, NULL);
 
866
        sp->wrk->bereq = sp->wrk->http[0];
 
867
        http_Setup(sp->wrk->bereq, sp->wrk->ws);
668
868
        http_FilterHeader(sp, HTTPH_R_FETCH);
 
869
        sp->wrk->connect_timeout = 0;
 
870
        sp->wrk->first_byte_timeout = 0;
 
871
        sp->wrk->between_bytes_timeout = 0;
669
872
        VCL_miss_method(sp);
670
 
        AZ(sp->obj->cacheable);
671
873
        switch(sp->handling) {
672
874
        case VCL_RET_ERROR:
673
 
                HSH_Drop(sp);
674
 
                VBE_free_bereq(&sp->bereq);
 
875
                HSH_DerefObjCore(sp);
675
876
                sp->step = STP_ERROR;
676
877
                return (0);
677
878
        case VCL_RET_PASS:
678
 
                HSH_Drop(sp);
679
 
                VBE_free_bereq(&sp->bereq);
 
879
                HSH_DerefObjCore(sp);
680
880
                sp->step = STP_PASS;
681
881
                return (0);
682
882
        case VCL_RET_FETCH:
683
883
                sp->step = STP_FETCH;
684
884
                return (0);
685
885
        case VCL_RET_RESTART:
686
 
                VBE_free_bereq(&sp->bereq);
 
886
                HSH_DerefObjCore(sp);
687
887
                INCOMPL();
688
888
        default:
689
889
                WRONG("Illegal action in vcl_miss{}");
730
930
        CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
731
931
        AZ(sp->obj);
732
932
 
 
933
        WS_Reset(sp->wrk->ws, NULL);
 
934
        sp->wrk->bereq = sp->wrk->http[0];
 
935
        http_Setup(sp->wrk->bereq, sp->wrk->ws);
733
936
        http_FilterHeader(sp, HTTPH_R_PASS);
734
937
 
 
938
        sp->wrk->connect_timeout = 0;
 
939
        sp->wrk->first_byte_timeout = 0;
 
940
        sp->wrk->between_bytes_timeout = 0;
735
941
        VCL_pass_method(sp);
736
942
        if (sp->handling == VCL_RET_ERROR) {
737
 
                VBE_free_bereq(&sp->bereq);
738
943
                sp->step = STP_ERROR;
739
944
                return (0);
740
945
        }
741
946
        assert(sp->handling == VCL_RET_PASS);
742
947
        sp->acct_req.pass++;
743
 
        HSH_Prealloc(sp, 0);
744
 
        sp->obj = sp->wrk->nobj;
745
 
        sp->wrk->nobj = NULL;
746
 
        sp->obj->busy = 1;
747
948
        sp->sendbody = 1;
748
949
        sp->step = STP_FETCH;
749
950
        return (0);
782
983
        CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
783
984
 
784
985
        sp->acct_req.pipe++;
 
986
        WS_Reset(sp->wrk->ws, NULL);
 
987
        sp->wrk->bereq = sp->wrk->http[0];
 
988
        http_Setup(sp->wrk->bereq, sp->wrk->ws);
785
989
        http_FilterHeader(sp, HTTPH_R_PIPE);
786
990
 
787
991
        VCL_pipe_method(sp);
791
995
        assert(sp->handling == VCL_RET_PIPE);
792
996
 
793
997
        PipeSession(sp);
794
 
        AZ(sp->bereq);
795
998
        AZ(sp->wrk->wfd);
 
999
        sp->wrk->bereq = NULL;
796
1000
        sp->step = STP_DONE;
797
1001
        return (0);
798
1002
}
818
1022
static int
819
1023
cnt_recv(struct sess *sp)
820
1024
{
 
1025
        unsigned recv_handling;
821
1026
 
822
1027
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
823
1028
        CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
824
1029
        AZ(sp->obj);
825
1030
 
826
 
        SES_ResetBackendTimeouts(sp);
827
 
 
828
1031
        /* By default we use the first backend */
829
1032
        AZ(sp->director);
830
1033
        sp->director = sp->vcl->director[0];
831
1034
        AN(sp->director);
832
1035
 
833
 
        sp->disable_esi = 0;
834
 
        
 
1036
        sp->disable_esi = 0;
 
1037
 
835
1038
        VCL_recv_method(sp);
 
1039
        recv_handling = sp->handling;
 
1040
 
836
1041
        if (sp->restarts >= params->max_restarts) {
837
1042
                if (sp->err_code == 0)
838
1043
                        sp->err_code = 503;
840
1045
                return (0);
841
1046
        }
842
1047
 
843
 
        sp->wantbody = (strcmp(sp->http->hd[HTTP_HDR_REQ].b, "HEAD") != 0);
 
1048
        SHA256_Init(sp->wrk->sha256ctx);
 
1049
        VCL_hash_method(sp);
 
1050
        assert(sp->handling == VCL_RET_HASH);
 
1051
        SHA256_Final(sp->digest, sp->wrk->sha256ctx);
 
1052
 
 
1053
        if (!strcmp(sp->http->hd[HTTP_HDR_REQ].b, "HEAD")) {
 
1054
                sp->wantbody = 0;
 
1055
                http_ForceGet(sp->http);
 
1056
        } else
 
1057
                sp->wantbody = 1;
 
1058
 
844
1059
        sp->sendbody = 0;
845
 
        switch(sp->handling) {
 
1060
        switch(recv_handling) {
846
1061
        case VCL_RET_LOOKUP:
847
1062
                /* XXX: discard req body, if any */
848
1063
                sp->step = STP_LOOKUP;
851
1066
                if (sp->esis > 0) {
852
1067
                        /* XXX: VSL something */
853
1068
                        INCOMPL();
854
 
                        sp->step = STP_DONE;
 
1069
                        /* sp->step = STP_DONE; */
855
1070
                        return (1);
856
1071
                }
857
1072
                sp->step = STP_PIPE;
889
1104
        AZ(sp->vcl);
890
1105
 
891
1106
        /* Update stats of various sorts */
892
 
        VSL_stats->client_req++;                        /* XXX not locked */
 
1107
        sp->wrk->stats.client_req++;
893
1108
        sp->t_req = TIM_real();
894
1109
        sp->wrk->lastused = sp->t_req;
895
1110
        sp->acct_req.req++;
1001
1216
         * do the syscall in the worker thread.
1002
1217
         */
1003
1218
        if (sp->step == STP_FIRST || sp->step == STP_START)
1004
 
                TCP_blocking(sp->fd);
 
1219
                (void)TCP_blocking(sp->fd);
1005
1220
 
 
1221
        /*
 
1222
         * NB: Once done is set, we can no longer touch sp!
 
1223
         */
1006
1224
        for (done = 0; !done; ) {
1007
1225
                assert(sp->wrk == w);
1008
1226
                /*
1012
1230
                CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
1013
1231
                CHECK_OBJ_ORNULL(sp->obj, OBJECT_MAGIC);
1014
1232
                CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
1015
 
                CHECK_OBJ_ORNULL(w->nobj, OBJECT_MAGIC);
1016
1233
                CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC);
 
1234
                WS_Assert(w->ws);
1017
1235
 
1018
1236
                switch (sp->step) {
1019
1237
#define STEP(l,u) \
1027
1245
                default:
1028
1246
                        WRONG("State engine misfire");
1029
1247
                }
1030
 
                CHECK_OBJ_ORNULL(w->nobj, OBJECT_MAGIC);
 
1248
                WS_Assert(w->ws);
1031
1249
                CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC);
1032
1250
        }
1033
1251
        WSL_Flush(w, 0);
1069
1287
 
1070
1288
static struct cli_proto debug_cmds[] = {
1071
1289
        { "debug.xid", "debug.xid",
1072
 
                "\tExamine or set XID\n", 0, 1, cli_debug_xid },
 
1290
                "\tExamine or set XID\n", 0, 1, "d", cli_debug_xid },
1073
1291
        { "debug.srandom", "debug.srandom",
1074
 
                "\tSeed the random(3) function\n", 0, 1, cli_debug_srandom },
 
1292
                "\tSeed the random(3) function\n", 0, 1, "d", cli_debug_srandom },
1075
1293
        { NULL }
1076
1294
};
1077
1295
 
1085
1303
 
1086
1304
        srandomdev();
1087
1305
        xids = random();
1088
 
        CLI_AddFuncs(DEBUG_CLI, debug_cmds);
 
1306
        CLI_AddFuncs(debug_cmds);
1089
1307
}
1090
1308
 
1091
1309