/* cache_acceptor.c */
-void vca_write(struct sess *sp, void *ptr, size_t len);
-void vca_write_obj(struct worker *w, struct sess *sp);
-void vca_flush(struct sess *sp);
void vca_return_session(struct sess *sp);
void vca_close_session(struct sess *sp, const char *why);
void VCA_Init(void);
/* cache_response.c */
void RES_Error(struct worker *w, struct sess *sp, int error, const char *msg);
+void RES_Flush(struct sess *sp);
+void RES_Write(struct sess *sp, void *ptr, size_t len);
+void RES_WriteObj(struct worker *w, struct sess *sp);
/* cache_vcl.c */
void VCL_Init(void);
static struct event accept_e[2 * HERITAGE_NSOCKS];
static TAILQ_HEAD(,sess) sesshead = TAILQ_HEAD_INITIALIZER(sesshead);
-
-/*--------------------------------------------------------------------
- * Write data to client
- * We try to use writev() if possible in order to minimize number of
- * syscalls made and packets sent. It also just might allow the worker
- * thread to complete the request without holding stuff locked.
- */
-
-void
-vca_flush(struct sess *sp)
-{
- int i;
-
- if (sp->fd < 0 || sp->wrk->niov == 0)
- return;
- i = writev(sp->fd, sp->wrk->iov, sp->wrk->niov);
- if (i != sp->wrk->liov)
- vca_close_session(sp, "remote closed");
- sp->wrk->liov = 0;
- sp->wrk->niov = 0;
-}
-
-void
-vca_write(struct sess *sp, void *ptr, size_t len)
-{
-
- if (sp->fd < 0 || len == 0)
- return;
- if (sp->wrk->niov == MAX_IOVS)
- vca_flush(sp);
- if (sp->fd < 0)
- return;
- sp->wrk->iov[sp->wrk->niov].iov_base = ptr;
- sp->wrk->iov[sp->wrk->niov++].iov_len = len;
- sp->wrk->liov += len;
-}
-
-void
-vca_write_obj(struct worker *w, struct sess *sp)
-{
- struct storage *st;
- unsigned u = 0;
- uint64_t bytes = 0;
-
-
- VSL(SLT_Status, sp->fd, "%u", sp->obj->response);
- VSL(SLT_Length, sp->fd, "%u", sp->obj->len);
-
- vca_write(sp, sp->obj->header, strlen(sp->obj->header));
-
- sbuf_clear(w->sb);
- sbuf_printf(w->sb, "Age: %u\r\n",
- sp->obj->age + sp->t_req - sp->obj->entered);
- sbuf_printf(w->sb, "Via: 1.1 varnish\r\n");
- sbuf_printf(w->sb, "X-Varnish: xid %u\r\n", sp->obj->xid);
- if (strcmp(sp->http->proto, "HTTP/1.1"))
- sbuf_printf(w->sb, "Connection: close\r\n");
- sbuf_printf(w->sb, "\r\n");
- sbuf_finish(w->sb);
- vca_write(sp, sbuf_data(w->sb), sbuf_len(w->sb));
- bytes += sbuf_len(w->sb);
- /* XXX: conditional request handling */
- if (!strcmp(sp->http->req, "GET")) {
- TAILQ_FOREACH(st, &sp->obj->store, list) {
- u += st->len;
- if (st->stevedore->send == NULL) {
- vca_write(sp, st->ptr, st->len);
- continue;
- }
- 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);
- }
- SES_ChargeBytes(sp, bytes + u);
- vca_flush(sp);
-}
-
-/*--------------------------------------------------------------------*/
-
static void
vca_tick(int a, short b, void *c)
{
cnt_deliver(struct sess *sp)
{
- vca_write_obj(sp->wrk, sp);
+ RES_WriteObj(sp->wrk, sp);
HSH_Deref(sp->obj);
sp->obj = NULL;
sp->step = STP_DONE;
sp->handling = VCL_RET_PASS;
if (sp->handling == VCL_RET_DELIVER) {
- vca_write_obj(sp->wrk, sp);
+ RES_WriteObj(sp->wrk, sp);
HSH_Deref(sp->obj);
sp->obj = NULL;
sp->step = STP_DONE;
if (i == 0 && bi == NULL)
return (1);
assert(i > 0);
- vca_write(sp, buf, i);
- vca_flush(sp);
+ RES_Write(sp, buf, i);
+ RES_Flush(sp);
cl -= i;
}
return (0);
if (u == 0)
break;
- vca_write(sp, p, q - p);
+ RES_Write(sp, p, q - p);
p = q;
}
if (bp - p < j)
j = bp - p;
- vca_write(sp, p, j);
+ RES_Write(sp, p, j);
p += j;
u -= j;
}
while (u > 0) {
if (http_GetTail(hp, u, &b, &e)) {
j = e - b;
- vca_write(sp, q, j);
+ RES_Write(sp, q, j);
u -= j;
} else
break;
}
- vca_flush(sp);
+ RES_Flush(sp);
while (u > 0) {
j = u;
if (j > sizeof buf)
j = sizeof buf;
i = read(fd, buf, j);
assert(i > 0);
- vca_write(sp, buf, i);
+ RES_Write(sp, buf, i);
u -= i;
- vca_flush(sp);
+ RES_Flush(sp);
}
}
return (0);
http_BuildSbuf(sp->fd, Build_Reply, w->sb, hp);
sbuf_cat(w->sb, "\r\n");
sbuf_finish(w->sb);
- vca_write(sp, sbuf_data(w->sb), sbuf_len(w->sb));
+ RES_Write(sp, sbuf_data(w->sb), sbuf_len(w->sb));
if (http_GetHdr(hp, "Content-Length", &b))
cls = pass_straight(sp, vc->fd, hp, b);
else {
cls = pass_straight(sp, vc->fd, hp, NULL);
}
- vca_flush(sp);
+ RES_Flush(sp);
if (http_GetHdr(hp, "Connection", &b) && !strcasecmp(b, "close"))
cls = 1;
*/
#include <stdio.h> /* XXX: for NULL ?? */
+#include <string.h> /* XXX: for NULL ?? */
#include <sys/types.h>
#include <sys/time.h>
#include "libvarnish.h"
+#include "shmlog.h"
#include "cache.h"
" </BODY>\r\n"
"</HTML>\r\n");
sbuf_finish(w->sb);
- vca_write(sp, sbuf_data(w->sb), sbuf_len(w->sb));
- vca_flush(sp);
+ RES_Write(sp, sbuf_data(w->sb), sbuf_len(w->sb));
+ RES_Flush(sp);
vca_close_session(sp, msg);
}
+
+
+/*--------------------------------------------------------------------
+ * Write data to client
+ * We try to use writev() if possible in order to minimize number of
+ * syscalls made and packets sent. It also just might allow the worker
+ * thread to complete the request without holding stuff locked.
+ */
+
+void
+RES_Flush(struct sess *sp)
+{
+ int i;
+
+ if (sp->fd < 0 || sp->wrk->niov == 0)
+ return;
+ i = writev(sp->fd, sp->wrk->iov, sp->wrk->niov);
+ if (i != sp->wrk->liov)
+ vca_close_session(sp, "remote closed");
+ sp->wrk->liov = 0;
+ sp->wrk->niov = 0;
+}
+
+void
+RES_Write(struct sess *sp, void *ptr, size_t len)
+{
+
+ if (sp->fd < 0 || len == 0)
+ return;
+ if (sp->wrk->niov == MAX_IOVS)
+ RES_Flush(sp);
+ if (sp->fd < 0)
+ return;
+ sp->wrk->iov[sp->wrk->niov].iov_base = ptr;
+ sp->wrk->iov[sp->wrk->niov++].iov_len = len;
+ sp->wrk->liov += len;
+}
+
+void
+RES_WriteObj(struct worker *w, struct sess *sp)
+{
+ struct storage *st;
+ unsigned u = 0;
+ uint64_t bytes = 0;
+
+
+ VSL(SLT_Status, sp->fd, "%u", sp->obj->response);
+ VSL(SLT_Length, sp->fd, "%u", sp->obj->len);
+
+ RES_Write(sp, sp->obj->header, strlen(sp->obj->header));
+
+ sbuf_clear(w->sb);
+ sbuf_printf(w->sb, "Age: %u\r\n",
+ sp->obj->age + sp->t_req - sp->obj->entered);
+ sbuf_printf(w->sb, "Via: 1.1 varnish\r\n");
+ sbuf_printf(w->sb, "X-Varnish: xid %u\r\n", sp->obj->xid);
+ if (strcmp(sp->http->proto, "HTTP/1.1"))
+ sbuf_printf(w->sb, "Connection: close\r\n");
+ sbuf_printf(w->sb, "\r\n");
+ sbuf_finish(w->sb);
+ RES_Write(sp, sbuf_data(w->sb), sbuf_len(w->sb));
+ bytes += sbuf_len(w->sb);
+ /* XXX: conditional request handling */
+ if (!strcmp(sp->http->req, "GET")) {
+ TAILQ_FOREACH(st, &sp->obj->store, list) {
+ u += st->len;
+ if (st->stevedore->send == NULL) {
+ RES_Write(sp, st->ptr, st->len);
+ continue;
+ }
+ 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);
+ }
+ SES_ChargeBytes(sp, bytes + u);
+ RES_Flush(sp);
+}