Commit a4b84805 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Rework the FetchHdr() and surroundings a litle bit, to get us a return

value that indicates if a failure should be retried.

Condition for retry is that the connection is recycled and fails before
we receive any data from the other end.

(The actual retry is not implemented yet)




git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5101 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent e4bf3933
......@@ -456,6 +456,8 @@ struct vbc {
struct vdi_simple *vdis;
int fd;
uint8_t recycled;
/* Timeouts */
double first_byte_timeout;
double between_bytes_timeout;
......
......@@ -94,6 +94,7 @@ VBE_ReleaseConn(struct vbc *vc)
assert(vc->backend == NULL);
assert(vc->fd < 0);
vc->recycled = 0;
if (params->cache_vbcs) {
Lck_Lock(&VBE_mtx);
VTAILQ_INSERT_HEAD(&vbcs, vc, list);
......@@ -364,11 +365,15 @@ vbe_GetVbe(struct sess *sp, struct vdi_simple *vs)
WSP(sp, SLT_Backend, "%d %s %s",
vc->fd, sp->director->vcl_name, bp->vcl_name);
vc->vdis = vs;
vc->recycled = 1;
return (vc);
}
VSC_main->backend_toolate++;
sp->vbc = vc;
VDI_CloseFd(sp);
WSL(sp->wrk, SLT_BackendClose, vc->fd, "%s", bp->vcl_name);
TCP_close(&vc->fd);
VBE_DropRefConn(bp);
vc->backend = NULL;
VBE_ReleaseConn(vc);
}
if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, vs)) {
......
......@@ -324,7 +324,15 @@ FetchReqBody(struct sess *sp)
return (0);
}
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------
* Send request, and receive the HTTP protocol response, but not the
* response body.
*
* Return value:
* -1 failure, not retryable
* 0 success
* 1 failure which can be retried.
*/
int
FetchHdr(struct sess *sp)
......@@ -333,35 +341,38 @@ FetchHdr(struct sess *sp)
struct worker *w;
char *b;
struct http *hp;
int retry = -1;
int i;
double tmo;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
w = sp->wrk;
AN(sp->director);
AZ(sp->obj);
if (sp->objcore != NULL) { /* pass has no objcore */
CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
AN(sp->objhead); /* details in hash_slinger.h */
AN(sp->objcore->flags & OC_F_BUSY);
}
/* Transmit request */
w = sp->wrk;
hp = sp->wrk->bereq;
sp->vbc = VDI_GetFd(NULL, sp);
if (sp->vbc == NULL) {
WSP(sp, SLT_FetchError, "no backend connection");
return (__LINE__);
return (-1);
}
vc = sp->vbc;
if (vc->recycled)
retry = 1;
/*
* Now that we know our backend, we can set a default Host:
* header if one is necessary.
* XXX: This possibly ought to go into the default VCL
* header if one is necessary. This cannot be done in the VCL
* because the backend may be chosen by a director.
*/
if (!http_GetHdr(hp, H_Host, &b))
VDI_AddHostHeader(sp);
......@@ -373,10 +384,11 @@ FetchHdr(struct sess *sp)
/* Deal with any message-body the request might have */
i = FetchReqBody(sp);
if (WRW_FlushRelease(w) || i > 0) {
WSP(sp, SLT_FetchError, "backend write error: %d", errno);
WSP(sp, SLT_FetchError, "backend write error: %d (%s)",
errno, strerror(errno));
VDI_CloseFd(sp);
/* XXX: other cleanup ? */
return (__LINE__);
return (retry);
}
/* Checkpoint the vsl.here */
......@@ -390,23 +402,31 @@ FetchHdr(struct sess *sp)
HTC_Init(sp->wrk->htc, sp->wrk->ws, vc->fd);
TCP_set_read_timeout(vc->fd, vc->first_byte_timeout);
tmo = vc->first_byte_timeout;
do {
i = HTC_Rx(sp->wrk->htc);
if (i < 0) {
WSP(sp, SLT_FetchError, "http first read error: %d %d (%s)",
i, errno, strerror(errno));
VDI_CloseFd(sp);
/* XXX: other cleanup ? */
/* Retryable if we never received anything */
return (i == -1 ? retry : -1);
}
TCP_set_read_timeout(vc->fd, vc->between_bytes_timeout);
while (i == 0) {
i = HTC_Rx(sp->wrk->htc);
if (i < 0) {
WSP(sp, SLT_FetchError,
"http read error: %d (%s)", errno, strerror(errno));
"http first read error: %d %d (%s)",
i, errno, strerror(errno));
VDI_CloseFd(sp);
/* XXX: other cleanup ? */
return (__LINE__);
}
if (vc->between_bytes_timeout != tmo) {
TCP_set_read_timeout(vc->fd, vc->between_bytes_timeout);
tmo = vc->between_bytes_timeout;
return (-1);
}
} while (i == 0);
}
hp = sp->wrk->beresp;
......@@ -414,7 +434,7 @@ FetchHdr(struct sess *sp)
WSP(sp, SLT_FetchError, "http format error");
VDI_CloseFd(sp);
/* XXX: other cleanup ? */
return (__LINE__);
return (-1);
}
return (0);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment