/* cache_http.c */
void HTTP_Init(void);
void http_CopyHttp(struct http *to, struct http *fm);
-void http_Write(struct worker *w, struct http *hp, int resp);
+unsigned http_Write(struct worker *w, struct http *hp, int resp);
void http_GetReq(int fd, struct http *to, struct http *fm);
void http_CopyReq(int fd, struct http *to, struct http *fm);
void http_CopyResp(int fd, struct http *to, struct http *fm);
/* cache_pass.c */
void PassSession(struct sess *sp);
-void PassBody(struct worker *w, struct sess *sp);
+void PassBody(struct sess *sp);
/* cache_pipe.c */
void PipeSession(struct sess *sp);
void WRK_QueueSession(struct sess *sp);
void WRK_Reset(struct worker *w, int *fd);
int WRK_Flush(struct worker *w);
-void WRK_Write(struct worker *w, const void *ptr, int len);
-void WRK_WriteH(struct worker *w, struct http_hdr *hh, const char *suf);
+unsigned WRK_Write(struct worker *w, const void *ptr, int len);
+unsigned WRK_WriteH(struct worker *w, struct http_hdr *hh, const char *suf);
/* cache_session.c [SES] */
void SES_Init(void);
FetchBody(sp);
HSH_Ref(sp->obj); /* get another, STP_DELIVER will deref */
HSH_Unbusy(sp->obj);
+ sp->wrk->acct.fetch++;
sp->step = STP_DELIVER;
return (0);
}
static int
cnt_passbody(struct sess *sp)
{
- PassBody(sp->wrk, sp);
+
+ sp->wrk->acct.pass++;
+ PassBody(sp);
sp->step = STP_DONE;
return (0);
}
cnt_pipe(struct sess *sp)
{
+ sp->wrk->acct.pipe++;
PipeSession(sp);
sp->step = STP_DONE;
return (0);
assert(sp->obj == NULL);
+ sp->wrk->acct.req++;
done = http_DissectRequest(sp->http, sp->fd);
if (done != 0) {
RES_Error(sp, done, NULL);
/*--------------------------------------------------------------------*/
-void
+unsigned
http_Write(struct worker *w, struct http *hp, int resp)
{
- unsigned u;
+ unsigned u, l;
if (resp) {
assert(hp->hd[HTTP_HDR_STATUS].b != NULL);
- WRK_WriteH(w, &hp->hd[HTTP_HDR_PROTO], " ");
- WRK_WriteH(w, &hp->hd[HTTP_HDR_STATUS], " ");
- WRK_WriteH(w, &hp->hd[HTTP_HDR_RESPONSE], "\r\n");
+ l = WRK_WriteH(w, &hp->hd[HTTP_HDR_PROTO], " ");
+ l += WRK_WriteH(w, &hp->hd[HTTP_HDR_STATUS], " ");
+ l += WRK_WriteH(w, &hp->hd[HTTP_HDR_RESPONSE], "\r\n");
} else {
assert(hp->hd[HTTP_HDR_URL].b != NULL);
- WRK_WriteH(w, &hp->hd[HTTP_HDR_REQ], " ");
- WRK_WriteH(w, &hp->hd[HTTP_HDR_URL], " ");
- WRK_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n");
+ l = WRK_WriteH(w, &hp->hd[HTTP_HDR_REQ], " ");
+ l += WRK_WriteH(w, &hp->hd[HTTP_HDR_URL], " ");
+ l += WRK_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n");
}
for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
assert(hp->hd[u].b != NULL);
assert(hp->hd[u].e != NULL);
- WRK_WriteH(w, &hp->hd[u], "\r\n");
+ l += WRK_WriteH(w, &hp->hd[u], "\r\n");
}
- WRK_Write(w, "\r\n", -1);
+ l += WRK_Write(w, "\r\n", -1);
+ return (l);
}
/*--------------------------------------------------------------------*/
if (i == 0 && bi == NULL)
return (1);
assert(i > 0);
- WRK_Write(sp->wrk, buf, i);
+ sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, buf, i);
if (WRK_Flush(sp->wrk))
vca_close_session(sp, "remote closed");
cl -= i;
if (u == 0)
break;
- WRK_Write(sp->wrk, p, q - p);
+ sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, q - p);
p = q;
}
if (bp - p < j)
j = bp - p;
- WRK_Write(sp->wrk, p, j);
+ sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, j);
p += j;
u -= j;
}
while (u > 0) {
if (http_GetTail(hp, u, &b, &e)) {
j = e - b;
- WRK_Write(sp->wrk, q, j);
+ sp->wrk->acct.bodybytes +=
+ WRK_Write(sp->wrk, q, j);
u -= j;
} else
break;
j = sizeof buf;
i = read(fd, buf, j);
assert(i > 0);
- WRK_Write(sp->wrk, buf, i);
+ sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, buf, i);
u -= i;
if (WRK_Flush(sp->wrk))
vca_close_session(sp, "remote closed");
/*--------------------------------------------------------------------*/
void
-PassBody(struct worker *w, struct sess *sp)
+PassBody(struct sess *sp)
{
struct vbe_conn *vc;
char *b;
http_CopyResp(sp->fd, sp->http, vc->http);
http_FilterHeader(sp->fd, sp->http, vc->http, HTTPH_A_PASS);
http_PrintfHeader(sp->fd, sp->http, "X-Varnish: %u", sp->xid);
- WRK_Reset(w, &sp->fd);
- http_Write(w, sp->http, 1);
+ WRK_Reset(sp->wrk, &sp->fd);
+ sp->wrk->acct.hdrbytes += http_Write(sp->wrk, sp->http, 1);
if (http_GetHdr(vc->http, H_Content_Length, &b))
cls = pass_straight(sp, vc->fd, vc->http, b);
cls = pass_straight(sp, vc->fd, vc->http, NULL);
}
- if (WRK_Flush(w))
+ if (WRK_Flush(sp->wrk))
vca_close_session(sp, "remote closed");
if (http_GetHdr(vc->http, H_Connection, &b) && !strcasecmp(b, "close"))
return (w->werr);
}
-void
+unsigned
WRK_WriteH(struct worker *w, struct http_hdr *hh, const char *suf)
{
+ unsigned u;
CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
assert(w != NULL);
assert(hh != NULL);
assert(hh->b != NULL);
assert(hh->e != NULL);
- WRK_Write(w, hh->b, hh->e - hh->b);
+ u = WRK_Write(w, hh->b, hh->e - hh->b);
if (suf != NULL)
- WRK_Write(w, suf, -1);
+ u += WRK_Write(w, suf, -1);
+ return (u);
}
-void
+unsigned
WRK_Write(struct worker *w, const void *ptr, int len)
{
CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
if (len == 0 || *w->wfd < 0)
- return;
+ return (0);
if (len == -1)
len = strlen(ptr);
if (w->niov == MAX_IOVS)
w->iov[w->niov].iov_base = (void*)(uintptr_t)ptr;
w->iov[w->niov++].iov_len = len;
w->liov += len;
+ return (len);
}
/*--------------------------------------------------------------------*/
if (sp->doclose != NULL)
http_PrintfHeader(sp->fd, sp->http, "Connection: close");
WRK_Reset(sp->wrk, &sp->fd);
- http_Write(sp->wrk, sp->http, 1);
+ sp->wrk->acct.hdrbytes += http_Write(sp->wrk, sp->http, 1);
/* XXX: conditional request handling */
if (!strcmp(sp->http->hd[HTTP_HDR_REQ].b, "GET")) {
TAILQ_FOREACH(st, &sp->obj->store, list) {
assert(st->stevedore != NULL);
u += st->len;
+ sp->wrk->acct.bodybytes += st->len;
if (st->stevedore->send == NULL) {
WRK_Write(sp->wrk, st->ptr, st->len);
- continue;
+ } else {
+ st->stevedore->send(st, sp);
+ sp->wrk->niov = 0;
+ sp->wrk->liov = 0;
}
- st->stevedore->send(st, sp,
- sp->wrk->iov, sp->wrk->niov, sp->wrk->liov);
- sp->wrk->niov = 0;
- sp->wrk->liov = 0;
}
assert(u == sp->obj->len);
}
typedef struct storage *storage_alloc_f(struct stevedore *, size_t size);
typedef void storage_trim_f(struct storage *, size_t size);
typedef void storage_free_f(struct storage *);
-typedef void storage_send_f(struct storage *, struct sess *, struct iovec *, int niovec, size_t liovec);
+typedef void storage_send_f(struct storage *, struct sess *);
struct stevedore {
const char *name;
/*--------------------------------------------------------------------*/
static void
-smf_send(struct storage *st, struct sess *sp, struct iovec *iov, int niov, size_t liov)
+smf_send(struct storage *st, struct sess *sp)
{
struct smf *smf;
int i;
smf = st->priv;
memset(&sfh, 0, sizeof sfh);
- sfh.headers = iov;
- sfh.hdr_cnt = niov;
+ sfh.headers = sp->wrk->iov;
+ sfh.hdr_cnt = sp->wrk->niov;
i = sendfile(smf->sc->fd,
sp->fd,
smf->offset,
st->len, &sfh, &sent, 0);
- if (sent == st->len + liov)
+ if (sent == st->len + sp->wrk->liov)
return;
vca_close_session(sp, "remote closed");
if (errno == EPIPE || errno == ENOTCONN)
return;
VSL(SLT_Debug, sp->fd,
"sent i=%d sent=%ju size=%ju liov=%ju errno=%d\n",
- i, (uintmax_t)sent, (uintmax_t)st->len, (uintmax_t)liov, errno);
+ i, (uintmax_t)sent, (uintmax_t)st->len,
+ (uintmax_t)sp->wrk->liov, errno);
}
/*--------------------------------------------------------------------*/
struct stevedore smf_stevedore = {
- "file",
- smf_init,
- smf_open,
- smf_alloc,
- smf_trim,
- smf_free,
- smf_send
+ .name = "file",
+ .init = smf_init,
+ .open = smf_open,
+ .alloc = smf_alloc,
+ .trim = smf_trim,
+ .free = smf_free,
+ .send = smf_send
};
#ifdef INCLUDE_TEST_DRIVER
}
struct stevedore sma_stevedore = {
- "malloc",
- NULL, /* init */
- NULL, /* open */
- sma_alloc,
- NULL, /* trim */
- sma_free
+ .name = "malloc",
+ .alloc = sma_alloc,
+ .free = sma_free
};