96
99
assert(sp->xid == 0);
98
101
i = HTC_Complete(sp->htc);
100
if (params->session_linger > 0) {
102
pfd[0].events = POLLIN;
104
i = poll(pfd, 1, params->session_linger);
106
WSL(sp->wrk, SLT_Debug, sp->fd, "herding");
107
VSL_stats->sess_herd++;
110
vca_return_session(sp);
102
if (i == 0 && params->session_linger > 0) {
104
pfd[0].events = POLLIN;
106
i = poll(pfd, 1, params->session_linger);
111
WSL(sp->wrk, SLT_Debug, sp->fd, "herding");
112
sp->wrk->stats.sess_herd++;
115
vca_return_session(sp);
117
119
sp->step = STP_START;
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");
125
vca_close_session(sp, "error");
123
vca_close_session(sp, "overflow");
126
if (i == -1 && Tlen(sp->htc->rxbuf) == 0 &&
127
(errno == 0 || errno == ECONNRESET))
128
vca_close_session(sp, "EOF");
130
vca_close_session(sp, "error");
253
259
WSL_Flush(sp->wrk, 0);
255
261
/* If we did an ESI include, don't mess up our state */
261
269
if (sp->fd >= 0 && sp->doclose != NULL) {
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.
266
TCP_linger(sp->fd, 0);
274
// XXX: not yet (void)TCP_linger(sp->fd, 0);
267
275
vca_close_session(sp, sp->doclose);
269
280
if (sp->fd < 0) {
271
VSL_stats->sess_closed++;
281
sp->wrk->stats.sess_closed++;
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);
280
292
i = HTC_Reinit(sp->htc);
282
VSL_stats->sess_pipeline++;
294
sp->wrk->stats.sess_pipeline++;
283
295
sp->step = STP_START;
286
298
if (Tlen(sp->htc->rxbuf)) {
287
VSL_stats->sess_readahead++;
299
sp->wrk->stats.sess_readahead++;
288
300
sp->step = STP_WAIT;
291
303
if (params->session_linger > 0) {
292
VSL_stats->sess_linger++;
304
sp->wrk->stats.sess_linger++;
293
305
sp->step = STP_WAIT;
296
VSL_stats->sess_herd++;
308
sp->wrk->stats.sess_herd++;
299
310
vca_return_session(sp);
408
421
cnt_fetch(struct sess *sp)
424
struct http *hp, *hp2;
426
unsigned handling, l, nhttp;
428
struct vsb *vary = NULL;
412
430
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
413
431
CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
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);
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.
446
sp->wrk->beresp1 = sp->wrk->http[2];
447
*sp->wrk->beresp1 = *sp->wrk->beresp;
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);
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);
432
RFC2616_cache_policy(sp, sp->obj->http); /* XXX -> VCL */
434
sp->err_code = http_GetStatus(sp->obj->http);
466
sp->err_code = http_GetStatus(sp->wrk->beresp);
469
* Initial cacheability determination per [RFC2616, 13.4]
470
* We do not support ranges yet, so 206 is out.
472
switch (sp->err_code) {
474
case 203: /* Non-Authoritative Information */
475
case 300: /* Multiple Choices */
476
case 301: /* Moved Permanently */
477
case 302: /* Moved Temporarily */
479
case 404: /* Not Found */
480
sp->wrk->cacheable = 1;
483
sp->wrk->cacheable = 0;
487
sp->wrk->entered = TIM_real();
489
sp->wrk->ttl = RFC2616_Ttl(sp);
491
if (sp->objcore == NULL)
492
sp->wrk->cacheable = 0;
495
sp->wrk->grace = NAN;
435
497
VCL_fetch_method(sp);
437
VBE_free_bereq(&sp->bereq);
439
switch (sp->handling) {
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
504
handling = sp->handling;
506
if (sp->objcore == NULL) {
507
/* This is a pass from vcl_recv */
509
sp->wrk->cacheable = 0;
510
} else if (!sp->wrk->cacheable) {
511
if (sp->objhead != NULL)
512
HSH_DerefObjCore(sp);
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
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);
526
varyl = vsb_len(vary);
534
l = http_EstimateWS(sp->wrk->beresp, HTTPH_A_INS, &nhttp);
539
/* Space for producing a Content-Length: header */
543
* XXX: If we have a Length: header, we should allocate the body
547
sp->obj = STV_NewObject(sp, l, sp->wrk->ttl, nhttp);
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. */
562
(void *)WS_Alloc(sp->obj->http->ws, varyl);
564
memcpy(sp->obj->vary, vsb_data(vary), varyl);
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);
580
/* Filter into object */
581
hp = sp->wrk->beresp;
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);
589
if (http_GetHdr(hp, H_Last_Modified, &b))
590
sp->obj->last_modified = TIM_parse(b);
600
sp->wrk->bereq = NULL;
601
sp->wrk->beresp = NULL;
602
sp->wrk->beresp1 = NULL;
604
sp->step = STP_ERROR;
608
if (sp->wrk->cacheable)
440
615
case VCL_RET_RESTART:
442
617
sp->director = NULL;
619
sp->wrk->bereq = NULL;
620
sp->wrk->beresp = NULL;
621
sp->wrk->beresp1 = NULL;
444
622
sp->step = STP_RECV;
446
624
case VCL_RET_PASS:
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;
451
630
case VCL_RET_DELIVER:
453
632
case VCL_RET_ERROR:
634
sp->wrk->bereq = NULL;
635
sp->wrk->beresp = NULL;
636
sp->wrk->beresp1 = NULL;
454
637
sp->step = STP_ERROR;
458
640
WRONG("Illegal action in vcl_fetch{}");
461
643
sp->obj->cacheable = 1;
462
if (sp->obj->objhead != NULL) {
644
if (sp->wrk->cacheable) {
464
645
EXP_Insert(sp->obj);
465
646
AN(sp->obj->ban);
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;
590
776
cnt_lookup(struct sess *sp)
592
779
struct object *o;
594
782
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
595
783
CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
597
if (sp->obj == NULL) {
598
HSH_Prepare(sp, sp->vcl->nhashcount);
600
assert(sp->handling == VCL_RET_HASH);
786
oc = HSH_Lookup(sp, &oh);
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 !
798
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
799
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
616
801
/* If we inserted a new object it's a miss */
618
VSL_stats->cache_miss++;
802
if (oc->flags & OC_F_BUSY) {
803
sp->wrk->stats.cache_miss++;
619
808
sp->step = STP_MISS;
624
VSL_stats->cache_hitpass++;
813
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
816
if (oc->flags & OC_F_PASS) {
817
sp->wrk->stats.cache_hitpass++;
625
818
WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
819
HSH_Deref(sp->wrk, &sp->obj);
627
822
sp->step = STP_PASS;
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;
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);
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:
674
VBE_free_bereq(&sp->bereq);
875
HSH_DerefObjCore(sp);
675
876
sp->step = STP_ERROR;
677
878
case VCL_RET_PASS:
679
VBE_free_bereq(&sp->bereq);
879
HSH_DerefObjCore(sp);
680
880
sp->step = STP_PASS;
682
882
case VCL_RET_FETCH:
683
883
sp->step = STP_FETCH;
685
885
case VCL_RET_RESTART:
686
VBE_free_bereq(&sp->bereq);
886
HSH_DerefObjCore(sp);
689
889
WRONG("Illegal action in vcl_miss{}");
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 },