#include "miniobj.h"
enum {
+ /* Fields from the first line of HTTP proto */
HTTP_HDR_REQ,
HTTP_HDR_URL,
HTTP_HDR_PROTO,
HTTP_HDR_STATUS,
HTTP_HDR_RESPONSE,
- /* add more here */
+ /* HTTP header lines */
HTTP_HDR_FIRST,
- HTTP_HDR_MAX = 32
+ HTTP_HDR_MAX = 32 /* XXX: should be #defined */
};
/* Note: intentionally not IOV_MAX */
#define MAX_IOVS (HTTP_HDR_MAX * 2)
/* Amount of per-worker logspace */
-#define WLOGSPACE 8192
+#define WLOGSPACE 8192 /* XXX: param ? */
struct cli;
struct vsb;
/*--------------------------------------------------------------------*/
+typedef struct {
+ char *b;
+ char *e;
+} txt;
+
+/*--------------------------------------------------------------------*/
+
enum step {
#define STEP(l, u) STP_##u,
#include "steps.h"
struct ws {
char *s; /* (S)tart of buffer */
- char *e; /* (E)nd of buffer */
char *f; /* (F)ree pointer */
char *r; /* (R)eserved length */
+ char *e; /* (E)nd of buffer */
};
/*--------------------------------------------------------------------
* HTTP Request/Response/Header handling structure.
*/
-typedef struct {
- char *b;
- char *e;
-} txt;
-
enum httpwhence {
- HTTP_Rx,
- HTTP_Tx,
- HTTP_Obj
+ HTTP_Rx = 1,
+ HTTP_Tx = 2,
+ HTTP_Obj = 3
};
struct http {
unsigned nhd;
};
+/*--------------------------------------------------------------------
+ * HTTP Protocol connection structure
+ */
+
struct http_conn {
unsigned magic;
#define HTTP_CONN_MAGIC 0x3e19edd1
const char *http_GetProto(const struct http *hp);
int http_HdrIs(const struct http *hp, const char *hdr, const char *val);
int http_DissectRequest(struct sess *sp);
-int http_DissectResponse(struct worker *w, struct http_conn *htc, struct http *sp);
+int http_DissectResponse(struct worker *w, const struct http_conn *htc, struct http *sp);
const char *http_DoConnection(struct http *hp);
void http_CopyHome(struct worker *w, int fd, struct http *hp);
void http_Unset(struct http *hp, const char *hdr);
void WSLR(struct worker *w, enum shmlogtag tag, int id, txt t);
void WSL(struct worker *w, enum shmlogtag tag, int id, const char *fmt, ...);
void WSL_Flush(struct worker *w);
+#define WSP(sess, tag, fmt, ...) \
+ WSL((sess)->wrk, tag, (sess)->fd, fmt, __VA_ARGS__)
+#define WSPR(sess, tag, txt) \
+ WSLR((sess)->wrk, tag, (sess)->fd, txt)
+
#define INCOMPL() do { \
VSL(SLT_Debug, 0, "INCOMPLETE AT: %s(%d)", __func__, __LINE__); \
fprintf(stderr,"INCOMPLETE AT: %s(%d)\n", (const char *)__func__, __LINE__); \
{
int i;
- VSL(SLT_SessionClose, sp->fd, why);
+ WSP(sp, SLT_SessionClose, "%s", why);
if (sp->fd >= 0) {
i = close(sp->fd);
assert(i == 0 || errno != EBADF); /* XXX EINVAL seen */
assert(vc->fd >= 0);
assert(vc->backend == sp->backend);
WSL(sp->wrk, SLT_BackendXID, vc->fd, "%u", sp->xid);
- WSL(sp->wrk, SLT_Backend, sp->fd, "%d %s", vc->fd,
- sp->backend->vcl_name);
+ WSP(sp, SLT_Backend, "%d %s", vc->fd, sp->backend->vcl_name);
return (vc);
}
return (NULL);
assert(vc->fd >= 0);
assert(vc->backend == sp->backend);
WSL(sp->wrk, SLT_BackendXID, vc->fd, "%u", sp->xid);
- WSL(sp->wrk, SLT_Backend, sp->fd, "%d %s", vc->fd,
- sp->backend->vcl_name);
+ WSP(sp, SLT_Backend, "%d %s", vc->fd, sp->backend->vcl_name);
return (vc);
}
return (NULL);
assert(vc->fd >= 0);
assert(vc->backend == sp->backend);
WSL(sp->wrk, SLT_BackendXID, vc->fd, "%u", sp->xid);
- WSL(sp->wrk, SLT_Backend, sp->fd, "%d %s", vc->fd,
- sp->backend->vcl_name);
+ WSP(sp, SLT_Backend, "%d %s", vc->fd, sp->backend->vcl_name);
return (vc);
}
return (NULL);
* We hit a busy object, disembark worker thread and expect
* hash code to restart us, still in STP_LOOKUP, later.
*/
- WSL(sp->wrk, SLT_Debug, sp->fd,
- "on waiting list on obj %u", sp->obj->xid);
+ WSP(sp, SLT_Debug, "on waiting list on obj %u", sp->obj->xid);
/*
* There is a non-zero risk that we come here more than once
* before we get through, in that case cnt_recv must be set
if (sp->obj->pass) {
VSL_stats->cache_hitpass++;
- WSL(sp->wrk, SLT_HitPass, sp->fd, "%u", sp->obj->xid);
+ WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
HSH_Deref(sp->obj);
sp->obj = NULL;
sp->step = STP_PASS;
}
VSL_stats->cache_hit++;
- WSL(sp->wrk, SLT_Hit, sp->fd, "%u", sp->obj->xid);
+ WSP(sp, SLT_Hit, "%u", sp->obj->xid);
sp->step = STP_HIT;
return (0);
}
/* Assign XID and log */
sp->xid = ++xids; /* XXX not locked */
- WSL(sp->wrk, SLT_ReqStart, sp->fd,
- "%s %s %u", sp->addr, sp->port, sp->xid);
+ WSP(sp, SLT_ReqStart, "%s %s %u", sp->addr, sp->port, sp->xid);
/* Borrow VCL reference from worker thread */
VCL_Refresh(&sp->wrk->vcl);
mklen = 1;
} else if (http_GetHdr(hp, H_Transfer_Encoding, &b)) {
/* XXX: AUGH! */
- VSL(SLT_Debug, vc->fd, "Invalid Transfer-Encoding");
+ WSL(sp->wrk, SLT_Debug, vc->fd, "Invalid Transfer-Encoding");
VBE_ClosedFd(sp->wrk, vc);
return (-1);
} else if (strcmp(http_GetProto(hp), "HTTP/1.1")) {
assert(*b == '\0');
b++;
assert(b == obj->hash + obj->hashlen);
- VSL(SLT_Debug, sp->fd, "Hash Match: %s", obj->hash);
+ WSP(sp, SLT_Debug, "Hash Match: %s", obj->hash);
return (0);
}
*b++ = '#';
}
*b++ = '\0';
- VSL(SLT_Debug, sp->fd, "Hash: %s", obj->hash);
+ WSP(sp, SLT_Debug, "Hash: %s", obj->hash);
assert(b <= obj->hash + obj->hashlen);
}
} else if (BAN_CheckObject(o,
h->hd[HTTP_HDR_URL].b, oh->hash)) {
o->ttl = 0;
- VSL(SLT_ExpBan, 0, "%u was banned", o->xid);
+ WSP(sp, SLT_ExpBan, "%u was banned", o->xid);
if (o->heap_idx != 0)
EXP_TTLchange(o);
} else if (o->vary == NULL || VRY_Match(sp, o->vary))
#include "http_headers.h"
#undef HTTPH
-enum httptag {
- HTTP_T_Request,
- HTTP_T_Response,
- HTTP_T_Status,
- HTTP_T_URL,
- HTTP_T_Protocol,
- HTTP_T_Header,
+#define C_SP (1<<0)
+#define C_CRLF (1<<1)
+#define C_LWS (C_CRLF | C_SP)
+#define C_CTL (1<<2)
+
+static unsigned char vctyptab[256] = {
+ ['\t'] = C_SP,
+ ['\n'] = C_CRLF,
+ ['\r'] = C_CRLF,
+ [' '] = C_SP,
};
-#define LOGMTX2(ax, bx) \
- [HTTP_T_##bx] = SLT_##ax##bx
+#define vctyp(x, y) (vctyptab[(int)(x)] & (y))
+
+#define LOGMTX2(ax, bx, cx) [bx] = SLT_##ax##cx
#define LOGMTX1(ax) { \
- LOGMTX2(ax, Request), \
- LOGMTX2(ax, Response), \
- LOGMTX2(ax, Status), \
- LOGMTX2(ax, URL), \
- LOGMTX2(ax, Protocol), \
- LOGMTX2(ax, Header), \
+ LOGMTX2(ax, HTTP_HDR_REQ, Request), \
+ LOGMTX2(ax, HTTP_HDR_RESPONSE, Response), \
+ LOGMTX2(ax, HTTP_HDR_STATUS, Status), \
+ LOGMTX2(ax, HTTP_HDR_URL, URL), \
+ LOGMTX2(ax, HTTP_HDR_PROTO, Protocol), \
+ LOGMTX2(ax, HTTP_HDR_FIRST, Header), \
}
-static enum shmlogtag logmtx[3][7] = {
+static enum shmlogtag logmtx[][HTTP_HDR_FIRST + 1] = {
[HTTP_Rx] = LOGMTX1(Rx),
[HTTP_Tx] = LOGMTX1(Tx),
[HTTP_Obj] = LOGMTX1(Obj)
};
static enum shmlogtag
-http2shmlog(const struct http *hp, enum httptag t)
+http2shmlog(const struct http *hp, int t)
{
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
- assert(/* hp->logtag >= HTTP_Rx && */hp->logtag <= HTTP_Obj);
- assert(/* t >= HTTP_T_Request && */t <= HTTP_T_Header);
+ if (t > HTTP_HDR_FIRST)
+ t = HTTP_HDR_FIRST;
+ assert(hp->logtag >= HTTP_Rx && hp->logtag <= HTTP_Obj);
+ assert(t >= HTTP_HDR_REQ && t <= HTTP_HDR_FIRST);
return (logmtx[hp->logtag][t]);
}
static void
-WSLH(struct worker *w, enum httptag t, int fd, const struct http *hp, unsigned hdr)
+WSLH(struct worker *w, int fd, const struct http *hp, unsigned hdr)
{
- WSLR(w, http2shmlog(hp, t), fd, hp->hd[hdr]);
+ WSLR(w, http2shmlog(hp, hdr), fd, hp->hd[hdr]);
}
/*--------------------------------------------------------------------*/
hp->hdf[hp->nhd] = 0;
hp->hd[hp->nhd].b = p;
hp->hd[hp->nhd].e = q;
- WSLH(w, HTTP_T_Header, fd, hp, hp->nhd);
+ WSLH(w, fd, hp, hp->nhd);
hp->nhd++;
} else {
VSL_stats->losthdr++;
return (0);
}
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Deal with first line of HTTP protocol message.
+ */
-int
-http_DissectRequest(struct sess *sp)
+static int
+http_splitline(struct worker *w, int fd, struct http *hp, const struct http_conn *htc, int h1, int h2, int h3)
{
char *p;
- struct http_conn *htc;
- struct http *hp;
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- htc = sp->htc;
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
- hp = sp->http;
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
- /* Assert a NUL at rx.e */
+ /* XXX: Assert a NUL at rx.e ? */
Tcheck(htc->rxbuf);
- hp->logtag = HTTP_Rx;
- for (p = htc->rxbuf.b ; isspace(*p); p++)
+ /* Skip leading LWS */
+ for (p = htc->rxbuf.b ; vctyp(*p, C_LWS); p++)
continue;
- /* First, the request type (GET/HEAD etc) */
- hp->hd[HTTP_HDR_REQ].b = p;
- for (; isalpha(*p); p++)
+ /* First field cannot contain SP, CRLF or CTL */
+ hp->hd[h1].b = p;
+ for (; !vctyp(*p, C_SP); p++)
+ if (vctyp(*p, C_CRLF | C_CTL))
+ return (400);
+ hp->hd[h1].e = p;
+
+ /* Skip SP */
+ for (; vctyp(*p, C_SP); p++)
;
- hp->hd[HTTP_HDR_REQ].e = p;
- WSLH(sp->wrk, HTTP_T_Request, sp->fd, hp, HTTP_HDR_REQ);
- *p++ = '\0';
- /* Next find the URI */
- while (isspace(*p) && *p != '\n')
- p++;
- if (*p == '\n') {
- WSLR(sp->wrk, SLT_HttpGarbage, sp->fd, htc->rxbuf);
- return (400);
- }
- hp->hd[HTTP_HDR_URL].b = p;
- while (!isspace(*p))
- p++;
- hp->hd[HTTP_HDR_URL].e = p;
- WSLH(sp->wrk, HTTP_T_URL, sp->fd, hp, HTTP_HDR_URL);
- if (*p == '\n') {
- WSLR(sp->wrk, SLT_HttpGarbage, sp->fd, htc->rxbuf);
- return (400);
- }
- *p++ = '\0';
+ /* Second field cannot contain SP, CRLF or CTL */
+ hp->hd[h2].b = p;
+ for (; !vctyp(*p, C_SP); p++)
+ if (vctyp(*p, C_CRLF | C_CTL))
+ return (400);
+ hp->hd[h2].e = p;
- /* Finally, look for protocol */
- while (isspace(*p) && *p != '\n')
- p++;
- if (*p == '\n') {
- WSLR(sp->wrk, SLT_HttpGarbage, sp->fd, htc->rxbuf);
- return (400);
+ /* Skip SP */
+ for (; vctyp(*p, C_SP); p++)
+ ;
+
+ /* Third field is optional and cannot contain CTL */
+ if (!vctyp(*p, C_CRLF)) {
+ hp->hd[h3].b = p;
+ for (; !vctyp(*p, C_CRLF); p++)
+ if (vctyp(*p, C_CTL))
+ return (400);
+ hp->hd[h3].e = p;
}
- hp->hd[HTTP_HDR_PROTO].b = p;
- while (!isspace(*p))
- p++;
- hp->hd[HTTP_HDR_PROTO].e = p;
- WSLH(sp->wrk, HTTP_T_Protocol, sp->fd, hp, HTTP_HDR_PROTO);
- if (*p != '\n')
- *p++ = '\0';
- while (isspace(*p) && *p != '\n')
- p++;
- if (*p != '\n') {
- WSLR(sp->wrk, SLT_HttpGarbage, sp->fd, htc->rxbuf);
- return (400);
+
+ /* Skip CRLF */
+ for (; vctyp(*p, C_CRLF); p++)
+ if (vctyp(*p, C_CTL))
+ return (400);
+
+ *hp->hd[h1].e = '\0';
+ WSLH(w, fd, hp, h1);
+
+ *hp->hd[h2].e = '\0';
+ WSLH(w, fd, hp, h2);
+
+ if (hp->hd[h3].e != NULL) {
+ *hp->hd[h3].e = '\0';
+ WSLH(w, fd, hp, h3);
}
- *p++ = '\0';
- return (http_dissect_hdrs(sp->wrk, hp, sp->fd, p, htc->rxbuf));
+ return (http_dissect_hdrs(w, hp, fd, p, htc->rxbuf));
}
/*--------------------------------------------------------------------*/
int
-http_DissectResponse(struct worker *w, struct http_conn *htc, struct http *hp)
+http_DissectRequest(struct sess *sp)
{
- char *p, *q;
+ struct http_conn *htc;
+ struct http *hp;
+ int i;
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ htc = sp->htc;
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
+ hp = sp->http;
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
- /* Assert a NUL at rx.e (?) */
- Tcheck(htc->rxbuf);
+
hp->logtag = HTTP_Rx;
- for (p = htc->rxbuf.b ; isspace(*p); p++)
- continue;
+ i = http_splitline(sp->wrk, sp->fd, hp, htc,
+ HTTP_HDR_REQ, HTTP_HDR_URL, HTTP_HDR_PROTO);
- if (memcmp(p, "HTTP/1.", 7)) {
- WSLR(w, SLT_HttpGarbage, htc->fd, htc->rxbuf);
- return (400);
- }
- /* First, protocol */
- hp->hd[HTTP_HDR_PROTO].b = p;
- while (!isspace(*p))
- p++;
- hp->hd[HTTP_HDR_PROTO].e = p;
- WSLH(w, HTTP_T_Protocol, htc->fd, hp, HTTP_HDR_PROTO);
- *p++ = '\0';
+ if (i != 0)
+ WSPR(sp, SLT_HttpGarbage, htc->rxbuf);
+ return (i);
+}
- /* Next find the status */
- while (isspace(*p))
- p++;
- hp->hd[HTTP_HDR_STATUS].b = p;
- while (!isspace(*p))
- p++;
- hp->hd[HTTP_HDR_STATUS].e = p;
- WSLH(w, HTTP_T_Status, htc->fd, hp, HTTP_HDR_STATUS);
- *p++ = '\0';
+/*--------------------------------------------------------------------*/
- /* Next find the response */
- while (isspace(*p))
- p++;
- hp->hd[HTTP_HDR_RESPONSE].b = p;
- while (*p != '\n')
- p++;
- for (q = p; q > hp->hd[HTTP_HDR_RESPONSE].b &&
- isspace(q[-1]); q--)
- continue;
- *q = '\0';
- hp->hd[HTTP_HDR_RESPONSE].e = q;
- WSLH(w, HTTP_T_Response, htc->fd, hp, HTTP_HDR_RESPONSE);
- p++;
+int
+http_DissectResponse(struct worker *w, const struct http_conn *htc, struct http *hp)
+{
+ int i;
+
+ CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
+ CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+ hp->logtag = HTTP_Rx;
+
+ i = http_splitline(w, htc->fd, hp, htc,
+ HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_RESPONSE);
- return (http_dissect_hdrs(w, hp, htc->fd, p, htc->rxbuf));
+ if (i != 0 || memcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.", 7))
+ WSLR(w, SLT_HttpGarbage, htc->fd, htc->rxbuf);
+ return (i);
}
/*--------------------------------------------------------------------*/
http_CopyHome(struct worker *w, int fd, struct http *hp)
{
unsigned u, l;
- enum httptag htt;
char *p;
for (u = 0; u < hp->nhd; u++) {
if (hp->hd[u].b == NULL)
continue;
- switch (u) {
- case HTTP_HDR_PROTO:
- htt = HTTP_T_Protocol;
- break;
- case HTTP_HDR_STATUS:
- htt = HTTP_T_Status;
- break;
- case HTTP_HDR_RESPONSE:
- htt = HTTP_T_Response;
- break;
- default:
- htt = HTTP_T_Header;
- break;
- }
if (hp->hd[u].b >= hp->ws->s && hp->hd[u].e <= hp->ws->e) {
- WSLH(w, htt, fd, hp, u);
+ WSLH(w, fd, hp, u);
continue;
}
l = Tlen(hp->hd[u]);
p = WS_Alloc(hp->ws, l + 1);
if (p != NULL) {
- WSLH(w, htt, fd, hp, u);
+ WSLH(w, fd, hp, u);
memcpy(p, hp->hd[u].b, l + 1);
hp->hd[u].b = p;
hp->hd[u].e = p + l;
if (resp) {
AN(hp->hd[HTTP_HDR_STATUS].b);
l = WRK_WriteH(w, &hp->hd[HTTP_HDR_PROTO], " ");
- WSLH(w, HTTP_T_Protocol, *w->wfd, hp, HTTP_HDR_PROTO);
+ WSLH(w, *w->wfd, hp, HTTP_HDR_PROTO);
l += WRK_WriteH(w, &hp->hd[HTTP_HDR_STATUS], " ");
- WSLH(w, HTTP_T_Status, *w->wfd, hp, HTTP_HDR_STATUS);
+ WSLH(w, *w->wfd, hp, HTTP_HDR_STATUS);
l += WRK_WriteH(w, &hp->hd[HTTP_HDR_RESPONSE], "\r\n");
- WSLH(w, HTTP_T_Response, *w->wfd, hp, HTTP_HDR_RESPONSE);
+ WSLH(w, *w->wfd, hp, HTTP_HDR_RESPONSE);
} else {
AN(hp->hd[HTTP_HDR_URL].b);
l = WRK_WriteH(w, &hp->hd[HTTP_HDR_REQ], " ");
- WSLH(w, HTTP_T_Request, *w->wfd, hp, HTTP_HDR_REQ);
+ WSLH(w, *w->wfd, hp, HTTP_HDR_REQ);
l += WRK_WriteH(w, &hp->hd[HTTP_HDR_URL], " ");
- WSLH(w, HTTP_T_URL, *w->wfd, hp, HTTP_HDR_URL);
+ WSLH(w, *w->wfd, hp, HTTP_HDR_URL);
l += WRK_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n");
- WSLH(w, HTTP_T_Protocol, *w->wfd, hp, HTTP_HDR_PROTO);
+ WSLH(w, *w->wfd, hp, HTTP_HDR_PROTO);
}
for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
AN(hp->hd[u].b);
AN(hp->hd[u].e);
l += WRK_WriteH(w, &hp->hd[u], "\r\n");
- WSLH(w, HTTP_T_Header, *w->wfd, hp, u);
+ WSLH(w, *w->wfd, hp, u);
}
l += WRK_Write(w, "\r\n", -1);
return (l);
void
HTTP_Init(void)
{
+ int i;
#define HTTPH(a, b, c, d, e, f, g) b[0] = (char)strlen(b + 1);
#include "http_headers.h"
#undef HTTPH
+
+ for (i = 1; i < 32; i++)
+ if (vctyptab[i] == 0)
+ vctyptab[i] = C_CTL;
+ vctyptab[127] = C_CTL;
}
{
char lm[64];
- WSL(sp->wrk, SLT_Length, sp->fd, "%u", 0);
+ WSP(sp, SLT_Length, "%u", 0);
http_ClrHeader(sp->http);
sp->http->logtag = HTTP_Tx;
if (sp->obj->response == 200 && sp->http->conds && res_do_conds(sp))
return;
- WSL(sp->wrk, SLT_Length, sp->fd, "%u", sp->obj->len);
+ WSP(sp, SLT_Length, "%u", sp->obj->len);
http_ClrHeader(sp->http);
sp->http->logtag = HTTP_Tx;
{ \
\
sp->handling = 0; \
- WSL(sp->wrk, SLT_VCL_call, sp->fd, "%s", #func); \
+ WSP(sp, SLT_VCL_call, "%s", #func); \
sp->vcl->func##_func(sp); \
- WSL(sp->wrk, SLT_VCL_return, sp->fd, "%s", \
- vcl_handlingname(sp->handling)); \
+ WSP(sp, SLT_VCL_return, "%s", vcl_handlingname(sp->handling)); \
assert(sp->handling & bitmap); \
assert(!(sp->handling & ~bitmap)); \
}
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
if (params->vcl_trace)
- WSL(sp->wrk, SLT_VCL_trace, sp->fd, "%u %d.%d", u,
+ WSP(sp, SLT_VCL_trace, "%u %d.%d", u,
sp->vcl->ref[u].line, sp->vcl->ref[u].pos);
}
} else {
b = vrt_assemble_string(hp, hdr + 1, p, ap);
if (b == NULL) {
- VSL(SLT_LostHeader, sp->fd, hdr + 1);
+ WSP(sp, SLT_LostHeader, "%s", hdr + 1);
} else {
http_Unset(hp, hdr);
http_SetHeader(sp->wrk, sp->fd, hp, b);
assert(num >= 100 && num <= 999);
p = WS_Alloc(sp->obj->http.ws, 4);
if (p == NULL)
- WSL(sp->wrk, SLT_LostHeader, sp->fd, "obj.status");
+ WSP(sp, SLT_LostHeader, "%s", "obj.status");
else
sprintf(p, "%d", num);
http_SetH(&sp->obj->http, HTTP_HDR_STATUS, p);
assert(num >= 100 && num <= 999);
p = WS_Alloc(sp->http->ws, 4);
if (p == NULL)
- WSL(sp->wrk, SLT_LostHeader, sp->fd, "resp.status");
+ WSP(sp, SLT_LostHeader, "%s", "resp.status");
else
sprintf(p, "%d", num);
http_SetH(sp->http, HTTP_HDR_STATUS, p);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
- WSL(sp->wrk, SLT_TTL, sp->fd, "%u VCL %.0f %.0f",
+ WSP(sp, SLT_TTL, "%u VCL %.0f %.0f",
sp->obj->xid, a, sp->t_req);
if (a < 0)
a = 0;
if (acln != NULL) {
if (ap->name == NULL) {
assert(r == 0);
- VSL(SLT_VCL_acl, sp->fd, "NO_MATCH %s", acln);
+ WSP(sp, SLT_VCL_acl, "NO_MATCH %s", acln);
return (r);
}
if (ap->priv == NULL) {
assert(r == 0);
- VSL(SLT_VCL_acl, sp->fd, "FAIL %s %s", acln, ap->desc);
+ WSP(sp, SLT_VCL_acl, "FAIL %s %s", acln, ap->desc);
return (r);
}
- VSL(SLT_VCL_acl, sp->fd, "%s %s %s",
- r ? "MATCH" : "NEG_MATCH", acln, ap->desc);
+ WSP(sp, SLT_VCL_acl, "%s %s %s",
+ r ? "MATCH" : "NEG_MATCH", acln, ap->desc);
}
return (r);
}
// Review all below this line ///////////////////////////////////////////////
+-e732 // Loss of sign (arg. no. 2) (int to unsigned
+-e737 // [45] Loss of sign in promotion from int to unsigned
+-e713 // Loss of precision (assignment) (unsigned long long to long long)
+-e574 // Signed-unsigned mix with relational
+-e712 // Loss of precision (assignment) (long long to
+-e747 // Significant prototype coercion (arg. no. 2) long
+
/*
-e767 // Macro redef (system queue.h vs ours )
--e574 // Signed-unsigned mix with relational
--e712 // Loss of precision (assignment) (long long to
--e747 // Significant prototype coercion (arg. no. 2) long
--e713 // Loss of precision (assignment) (unsigned long long to long long)
-e506 // Constant value boolean
-e818 // Pointer parameter '...' could be declared as pointing to const
-e774 // Boolean within 'if' always evaluates to False
-e534 // Ignoring return value of function
-e557 // unrecog format
--e732 // Loss of sign (arg. no. 2) (int to unsigned
--e737 // [45] Loss of sign in promotion from int to unsigned
*/
}
/* calculated TTL, Our time, Date, Expires, max-age, age */
- WSL(sp->wrk, SLT_TTL, sp->fd, "%u RFC %d %d %d %d %d %d", sp->xid,
+ WSP(sp, SLT_TTL, "%u RFC %d %d %d %d %d %d", sp->xid,
(int)(ttd - obj->entered), (int)obj->entered, (int)h_date,
(int)h_expires, (int)u1, (int)u2);
static unsigned char *logstart;
static MTX vsl_mtx;
-/*
- * This variant copies a byte-range directly to the log, without
- * taking the detour over sprintf()
- */
static void
vsl_wrap(void)
loghead->ptr = 0;
}
-/*--------------------------------------------------------------------*/
+static void
+vsl_hdr(enum shmlogtag tag, unsigned char *p, unsigned len, int id)
+{
+
+ p[1] = len & 0xff;
+ p[2] = (id >> 8) & 0xff;
+ p[3] = id & 0xff;
+ p[4 + len] = '\0';
+ p[5 + len] = SLT_ENDMARKER;
+ /* XXX: Write barrier here */
+ p[0] = tag;
+}
+
+/*--------------------------------------------------------------------
+ * This variant copies a byte-range directly to the log, without
+ * taking the detour over sprintf()
+ */
void
VSLR(enum shmlogtag tag, int id, txt t)
vsl_wrap();
p = logstart + loghead->ptr;
loghead->ptr += 5 + l;
- p[5 + l] = SLT_ENDMARKER;
assert(loghead->ptr < loghead->size);
UNLOCKSHM(&vsl_mtx);
- p[1] = l & 0xff;
- p[2] = (id >> 8) & 0xff;
- p[3] = id & 0xff;
memcpy(p + 4, t.b, l);
- p[4 + l] = '\0';
- /* XXX: memory barrier */
- p[0] = tag;
+ vsl_hdr(tag, p, l, id);
}
/*--------------------------------------------------------------------*/
t.b = (void*)(uintptr_t)fmt;
t.e = strchr(fmt, '\0');
VSLR(tag, id, t);
- return;
+ } else {
+ LOCKSHM(&vsl_mtx);
+ VSL_stats->shm_writes++;
+ VSL_stats->shm_records++;
+ assert(loghead->ptr < loghead->size);
+
+ /* Wrap if we cannot fit a full size record */
+ if (loghead->ptr + 5 + 255 + 1 >= loghead->size)
+ vsl_wrap();
+
+ p = logstart + loghead->ptr;
+ n = vsnprintf((char *)(p + 4), 256, fmt, ap);
+ if (n > 255)
+ n = 255; /* we truncate long fields */
+ vsl_hdr(tag, p, n, id);
+ loghead->ptr += 5 + n;
+ assert(loghead->ptr < loghead->size);
+ UNLOCKSHM(&vsl_mtx);
}
-
- LOCKSHM(&vsl_mtx);
- VSL_stats->shm_writes++;
- VSL_stats->shm_records++;
- assert(loghead->ptr < loghead->size);
-
- /* Wrap if we cannot fit a full size record */
- if (loghead->ptr + 5 + 255 + 1 >= loghead->size)
- vsl_wrap();
-
- p = logstart + loghead->ptr;
- n = 0;
- n = vsnprintf((char *)(p + 4), 256, fmt, ap);
- if (n > 255)
- n = 255; /* we truncate long fields */
- p[1] = n & 0xff;
- p[2] = (id >> 8) & 0xff;
- p[3] = id & 0xff;
- p[4 + n] = '\0';;
- p[5 + n] = SLT_ENDMARKER;
- p[0] = tag;
-
- loghead->ptr += 5 + n;
- assert(loghead->ptr < loghead->size);
-
- UNLOCKSHM(&vsl_mtx);
-
va_end(ap);
}
p[l] = SLT_ENDMARKER;
loghead->ptr += l;
assert(loghead->ptr < loghead->size);
+ /* XXX: memory barrier here */
p[0] = w->wlog[0];
UNLOCKSHM(&vsl_mtx);
w->wlp = w->wlog;
p = w->wlp;
w->wlp += 5 + l;
assert(w->wlp < w->wle);
- p[5 + l] = SLT_ENDMARKER;
-
- p[1] = l & 0xff;
- p[2] = (id >> 8) & 0xff;
- p[3] = id & 0xff;
memcpy(p + 4, t.b, l);
- p[4 + l] = '\0';
- p[0] = tag;
+ vsl_hdr(tag, p, l, id);
w->wlr++;
}
t.b = (void*)(uintptr_t)fmt;
t.e = strchr(fmt, '\0');
WSLR(w, tag, id, t);
- return;
+ } else {
+ assert(w->wlp < w->wle);
+
+ /* Wrap if we cannot fit a full size record */
+ if (w->wlp + 5 + 255 + 1 >= w->wle)
+ WSL_Flush(w);
+
+ p = w->wlp;
+ n = vsnprintf((char *)(p + 4), 256, fmt, ap);
+ if (n > 255)
+ n = 255; /* we truncate long fields */
+ vsl_hdr(tag, p, n, id);
+ w->wlp += 5 + n;
+ assert(w->wlp < w->wle);
+ w->wlr++;
}
-
- assert(w->wlp < w->wle);
-
- /* Wrap if we cannot fit a full size record */
- if (w->wlp + 5 + 255 + 1 >= w->wle)
- WSL_Flush(w);
-
- p = w->wlp;
- n = 0;
- n = vsnprintf((char *)(p + 4), 256, fmt, ap);
- if (n > 255)
- n = 255; /* we truncate long fields */
- p[1] = n & 0xff;
- p[2] = (id >> 8) & 0xff;
- p[3] = id & 0xff;
- p[4 + n] = '\0';;
- p[5 + n] = SLT_ENDMARKER;
- p[0] = tag;
-
- w->wlp += 5 + n;
- assert(w->wlp < w->wle);
- w->wlr++;
va_end(ap);
}