void http_PutResponse(struct worker *w, int fd, struct http *to, const char *response);
void http_PrintfHeader(struct worker *w, int fd, struct http *to, const char *fmt, ...);
void http_SetHeader(struct worker *w, int fd, struct http *to, const char *hdr);
+void http_SetH(struct http *to, unsigned n, const char *fm);
void http_Setup(struct http *ht, void *space, unsigned len);
int http_GetHdr(struct http *hp, const char *hdr, char **ptr);
int http_GetHdrField(struct http *hp, const char *hdr, const char *field, char **ptr);
void http_DoConnection(struct sess *sp);
void http_CopyHome(struct worker *w, int fd, struct http *hp);
void http_Unset(struct http *hp, const char *hdr);
-void http_LogLostHeader(struct worker *w, int fd, struct http *hp, const char *hdr);
#define HTTPH(a, b, c, d, e, f, g) extern char b[];
HTTP_T_URL,
HTTP_T_Protocol,
HTTP_T_Header,
- HTTP_T_LostHeader,
};
#define LOGMTX2(ax, bx) \
LOGMTX2(ax, URL), \
LOGMTX2(ax, Protocol), \
LOGMTX2(ax, Header), \
- LOGMTX2(ax, LostHeader) \
}
static enum shmlogtag logmtx[3][7] = {
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
assert(/* hp->logtag >= HTTP_Rx && */hp->logtag <= HTTP_Obj);
- assert(/* t >= HTTP_T_Request && */t <= HTTP_T_LostHeader);
+ assert(/* t >= HTTP_T_Request && */t <= HTTP_T_Header);
return (logmtx[hp->logtag][t]);
}
WSLR(w, http2shmlog(hp, t), fd, hp->hd[hdr].b, hp->hd[hdr].e);
}
-void
-http_LogLostHeader(struct worker *w, int fd, struct http *hp, const char *hdr)
-{
- WSLR(w, http2shmlog(hp, HTTP_T_LostHeader), fd, hdr + 1, hdr + hdr[0]);
-}
-
/*--------------------------------------------------------------------*/
/* List of canonical HTTP response code names from RFC2616 */
hp->nhd++;
} else {
VSL_stats->losthdr++;
- WSLR(w, http2shmlog(hp, HTTP_T_LostHeader), fd, p, q);
+ WSLR(w, SLT_LostHeader, fd, p, q);
}
}
return (0);
/*--------------------------------------------------------------------*/
-static void
-http_seth(struct http *to, unsigned n, const char *fm)
+void
+http_SetH(struct http *to, unsigned n, const char *fm)
{
assert(n < HTTP_HDR_MAX);
CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC);
CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
if (forceget)
- http_seth(to, HTTP_HDR_REQ, "GET");
+ http_SetH(to, HTTP_HDR_REQ, "GET");
else
http_copyh(to, fm, HTTP_HDR_REQ);
http_copyh(to, fm, HTTP_HDR_URL);
- http_seth(to, HTTP_HDR_PROTO, "HTTP/1.1");
+ http_SetH(to, HTTP_HDR_PROTO, "HTTP/1.1");
}
void
CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC);
CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
if (params->client_http11)
- http_seth(to, HTTP_HDR_PROTO, "HTTP/1.1");
+ http_SetH(to, HTTP_HDR_PROTO, "HTTP/1.1");
else
http_copyh(to, fm, HTTP_HDR_PROTO);
http_copyh(to, fm, HTTP_HDR_STATUS);
{
CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
- http_seth(to, HTTP_HDR_PROTO, proto);
- http_seth(to, HTTP_HDR_STATUS, status);
- http_seth(to, HTTP_HDR_RESPONSE, response);
+ http_SetH(to, HTTP_HDR_PROTO, proto);
+ http_SetH(to, HTTP_HDR_STATUS, status);
+ http_SetH(to, HTTP_HDR_RESPONSE, response);
}
static void
to->nhd++;
} else {
VSL_stats->losthdr++;
- WSLH(w, HTTP_T_LostHeader, fd, fm, n);
+ WSLH(w, SLT_LostHeader, fd, fm, n);
}
}
hp->hd[u].b = p;
hp->hd[u].e = p + l;
} else {
- WSLH(w, HTTP_T_LostHeader, fd, hp, u);
+ WSLH(w, SLT_LostHeader, fd, hp, u);
hp->hd[u].b = NULL;
hp->hd[u].e = NULL;
}
CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
if (to->nhd >= HTTP_HDR_MAX) {
VSL_stats->losthdr++;
- WSL(w, http2shmlog(to, HTTP_T_LostHeader), fd, "%s", hdr);
+ WSL(w, SLT_LostHeader, fd, "%s", hdr);
return;
}
- http_seth(to, to->nhd++, hdr);
+ http_SetH(to, to->nhd++, hdr);
}
/*--------------------------------------------------------------------*/
l = (e - string);
p = WS_Alloc(to->ws, l + 1);
if (p == NULL) {
- WSL(w, http2shmlog(to, HTTP_T_LostHeader), fd, "%s", string);
+ WSL(w, SLT_LostHeader, fd, "%s", string);
to->hd[field].b = NULL;
to->hd[field].e = NULL;
} else {
va_end(ap);
if (n + 1 >= l || to->nhd >= HTTP_HDR_MAX) {
VSL_stats->losthdr++;
- WSL(w, http2shmlog(to, HTTP_T_LostHeader), fd, "%s", to->ws->f);
+ WSL(w, SLT_LostHeader, fd, "%s", to->ws->f);
WS_Release(to->ws, 0);
} else {
to->hd[to->nhd].b = to->ws->f;
/*--------------------------------------------------------------------*/
+static char *
+vrt_assemble_string(struct http *hp, const char *p, va_list ap)
+{
+ char *b, *e;
+ unsigned u, x;
+
+ u = WS_Reserve(hp->ws, 0);
+ e = b = hp->ws->f;
+ *e = '\0';
+ while (p != NULL) {
+ x = strlen(p);
+ if (x + 1 < u)
+ memcpy(e, p, x);
+ e += x;
+ p = va_arg(ap, const char *);
+ }
+ *e = '\0';
+ if (e > b + u) {
+ WS_Release(hp->ws, 0);
+ return (NULL);
+ } else {
+ WS_Release(hp->ws, 1 + e - b);
+ return (b);
+ }
+}
+
+/*--------------------------------------------------------------------*/
+
void
VRT_SetHdr(struct sess *sp , enum gethdr_e where, const char *hdr, ...)
{
struct http *hp;
va_list ap;
const char *p;
- char *b, *e;
- unsigned u, x;
+ char *b;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
hp = vrt_selecthttp(sp, where);
if (p == NULL) {
http_Unset(hp, hdr);
} else {
- u = WS_Reserve(hp->ws, 0);
- e = b = hp->ws->f;
- *e = '\0';
- x = strlen(hdr + 1);
- if (x + 1 < u)
- memcpy(e, hdr + 1, x);
- e += x;
- if (1 + 1 < u)
- *e++ = ' ';
- while (p != NULL) {
- x = strlen(p);
- if (x + 1 < u)
- memcpy(e, p, x);
- e += x;
- p = va_arg(ap, const char *);
- }
- *e = '\0';
- if (e > b + u) {
- http_LogLostHeader(sp->wrk, sp->fd, hp, hdr);
- WS_Release(hp->ws, 0);
-
+ b = vrt_assemble_string(hp, p, ap);
+ if (b == NULL) {
+ VSL(SLT_LostHeader, sp->fd, hdr + 1);
} else {
- WS_Release(hp->ws, 1 + e - b);
http_Unset(hp, hdr);
http_SetHeader(sp->wrk, sp->fd, hp, b);
}
/*--------------------------------------------------------------------*/
+static void
+vrt_do_string(struct worker *w, int fd, struct http *hp, int fld, const char *err, const char *p, va_list ap)
+{
+ char *b;
+
+ AN(p);
+ AN(hp);
+ b = vrt_assemble_string(hp, p, ap);
+ if (b == NULL) {
+ WSL(w, SLT_LostHeader, fd, err);
+ } else {
+ http_SetH(hp, fld, b);
+ }
+ va_end(ap);
+}
+
+#define VRT_DO_HDR(obj, hdr, http, fld) \
+void \
+VRT_l_##obj##_##hdr(struct sess *sp, const char *p, ...) \
+{ \
+ va_list ap; \
+ \
+ AN(p); \
+ va_start(ap, p); \
+ vrt_do_string(sp->wrk, sp->fd, \
+ http, fld, #obj "." #hdr, p, ap); \
+ va_end(ap); \
+}
+
+VRT_DO_HDR(req, request, sp->http, HTTP_HDR_REQ)
+VRT_DO_HDR(req, url, sp->http, HTTP_HDR_URL)
+VRT_DO_HDR(req, proto, sp->http, HTTP_HDR_PROTO)
+VRT_DO_HDR(bereq, request, sp->bereq->http, HTTP_HDR_REQ)
+VRT_DO_HDR(bereq, url, sp->bereq->http, HTTP_HDR_URL)
+VRT_DO_HDR(bereq, proto, sp->bereq->http, HTTP_HDR_PROTO)
+VRT_DO_HDR(obj, proto, &sp->obj->http, HTTP_HDR_PROTO)
+VRT_DO_HDR(obj, response, &sp->obj->http, HTTP_HDR_RESPONSE)
+VRT_DO_HDR(resp, proto, sp->bereq->http, HTTP_HDR_PROTO)
+VRT_DO_HDR(resp, response, sp->bereq->http, HTTP_HDR_RESPONSE)
+
+#if 0
+VRT_DO_HDR(obj, status, &sp->obj->http, HTTP_HDR_STATUS)
+VRT_DO_HDR(resp, status, sp->bereq->http, HTTP_HDR_STATUS)
+#endif
+/*--------------------------------------------------------------------*/
+
void
VRT_handling(struct sess *sp, unsigned hand)
{
SLTM(RxURL)
SLTM(RxProtocol)
SLTM(RxHeader)
-SLTM(RxLostHeader)
SLTM(TxRequest)
SLTM(TxResponse)
SLTM(TxURL)
SLTM(TxProtocol)
SLTM(TxHeader)
-SLTM(TxLostHeader)
SLTM(ObjRequest)
SLTM(ObjResponse)
SLTM(ObjURL)
SLTM(ObjProtocol)
SLTM(ObjHeader)
-SLTM(ObjLostHeader)
+
+SLTM(LostHeader)
SLTM(TTL)
SLTM(VCL_acl)
struct sockaddr * VRT_r_client_ip(struct sess *);
struct sockaddr * VRT_r_server_ip(struct sess *);
const char * VRT_r_req_request(struct sess *);
+void VRT_l_req_request(struct sess *, const char *, ...);
const char * VRT_r_req_url(struct sess *);
+void VRT_l_req_url(struct sess *, const char *, ...);
const char * VRT_r_req_proto(struct sess *);
+void VRT_l_req_proto(struct sess *, const char *, ...);
void VRT_l_req_hash(struct sess *, const char *);
struct backend * VRT_r_req_backend(struct sess *);
void VRT_l_req_backend(struct sess *, struct backend *);
const char * VRT_r_bereq_request(struct sess *);
-void VRT_l_bereq_request(struct sess *, const char *);
+void VRT_l_bereq_request(struct sess *, const char *, ...);
const char * VRT_r_bereq_url(struct sess *);
-void VRT_l_bereq_url(struct sess *, const char *);
+void VRT_l_bereq_url(struct sess *, const char *, ...);
const char * VRT_r_bereq_proto(struct sess *);
-void VRT_l_bereq_proto(struct sess *, const char *);
+void VRT_l_bereq_proto(struct sess *, const char *, ...);
const char * VRT_r_obj_proto(struct sess *);
-void VRT_l_obj_proto(struct sess *, const char *);
+void VRT_l_obj_proto(struct sess *, const char *, ...);
int VRT_r_obj_status(struct sess *);
void VRT_l_obj_status(struct sess *, int);
const char * VRT_r_obj_response(struct sess *);
-void VRT_l_obj_response(struct sess *, const char *);
+void VRT_l_obj_response(struct sess *, const char *, ...);
unsigned VRT_r_obj_valid(struct sess *);
void VRT_l_obj_valid(struct sess *, unsigned);
unsigned VRT_r_obj_cacheable(struct sess *);
void VRT_l_obj_ttl(struct sess *, double);
double VRT_r_obj_lastuse(struct sess *);
const char * VRT_r_resp_proto(struct sess *);
-void VRT_l_resp_proto(struct sess *, const char *);
+void VRT_l_resp_proto(struct sess *, const char *, ...);
int VRT_r_resp_status(struct sess *);
void VRT_l_resp_status(struct sess *, int);
const char * VRT_r_resp_response(struct sess *);
-void VRT_l_resp_response(struct sess *, const char *);
+void VRT_l_resp_response(struct sess *, const char *, ...);
double VRT_r_now(struct sess *);
}
vcc_NextToken(tl);
vcc_StringVal(tl);
- if (vp->hdr != NULL) {
- while (tl->t->tok != ';') {
- Fb(tl, 0, ", ");
- vcc_StringVal(tl);
- }
- Fb(tl, 0, ", 0");
+ while (tl->t->tok != ';') {
+ Fb(tl, 0, ", ");
+ vcc_StringVal(tl);
}
- Fb(tl, 0, ");\n");
+ Fb(tl, 0, ", 0);\n");
break;
default:
vsb_printf(tl->sb,
vsb_cat(sb, "struct sockaddr * VRT_r_client_ip(struct sess *);\n");
vsb_cat(sb, "struct sockaddr * VRT_r_server_ip(struct sess *);\n");
vsb_cat(sb, "const char * VRT_r_req_request(struct sess *);\n");
+ vsb_cat(sb, "void VRT_l_req_request(struct sess *, const char *, ...);\n");
vsb_cat(sb, "const char * VRT_r_req_url(struct sess *);\n");
+ vsb_cat(sb, "void VRT_l_req_url(struct sess *, const char *, ...);\n");
vsb_cat(sb, "const char * VRT_r_req_proto(struct sess *);\n");
+ vsb_cat(sb, "void VRT_l_req_proto(struct sess *, const char *, ...);\n");
vsb_cat(sb, "void VRT_l_req_hash(struct sess *, const char *);\n");
vsb_cat(sb, "struct backend * VRT_r_req_backend(struct sess *);\n");
vsb_cat(sb, "void VRT_l_req_backend(struct sess *, struct backend *);\n");
vsb_cat(sb, "const char * VRT_r_bereq_request(struct sess *);\n");
- vsb_cat(sb, "void VRT_l_bereq_request(struct sess *, const char *);\n");
+ vsb_cat(sb, "void VRT_l_bereq_request(struct sess *, const char *, ...);\n");
vsb_cat(sb, "const char * VRT_r_bereq_url(struct sess *);\n");
- vsb_cat(sb, "void VRT_l_bereq_url(struct sess *, const char *);\n");
+ vsb_cat(sb, "void VRT_l_bereq_url(struct sess *, const char *, ...);\n");
vsb_cat(sb, "const char * VRT_r_bereq_proto(struct sess *);\n");
- vsb_cat(sb, "void VRT_l_bereq_proto(struct sess *, const char *);\n");
+ vsb_cat(sb, "void VRT_l_bereq_proto(struct sess *, const char *, ...);\n");
vsb_cat(sb, "const char * VRT_r_obj_proto(struct sess *);\n");
- vsb_cat(sb, "void VRT_l_obj_proto(struct sess *, const char *);\n");
+ vsb_cat(sb, "void VRT_l_obj_proto(struct sess *, const char *, ...);\n");
vsb_cat(sb, "int VRT_r_obj_status(struct sess *);\n");
vsb_cat(sb, "void VRT_l_obj_status(struct sess *, int);\n");
vsb_cat(sb, "const char * VRT_r_obj_response(struct sess *);\n");
- vsb_cat(sb, "void VRT_l_obj_response(struct sess *, const char *);\n");
+ vsb_cat(sb, "void VRT_l_obj_response(struct sess *, const char *, ...);\n");
vsb_cat(sb, "unsigned VRT_r_obj_valid(struct sess *);\n");
vsb_cat(sb, "void VRT_l_obj_valid(struct sess *, unsigned);\n");
vsb_cat(sb, "unsigned VRT_r_obj_cacheable(struct sess *);\n");
vsb_cat(sb, "void VRT_l_obj_ttl(struct sess *, double);\n");
vsb_cat(sb, "double VRT_r_obj_lastuse(struct sess *);\n");
vsb_cat(sb, "const char * VRT_r_resp_proto(struct sess *);\n");
- vsb_cat(sb, "void VRT_l_resp_proto(struct sess *, const char *);\n");
+ vsb_cat(sb, "void VRT_l_resp_proto(struct sess *, const char *, ...);\n");
vsb_cat(sb, "int VRT_r_resp_status(struct sess *);\n");
vsb_cat(sb, "void VRT_l_resp_status(struct sess *, int);\n");
vsb_cat(sb, "const char * VRT_r_resp_response(struct sess *);\n");
- vsb_cat(sb, "void VRT_l_resp_response(struct sess *, const char *);\n");
+ vsb_cat(sb, "void VRT_l_resp_response(struct sess *, const char *, ...);\n");
vsb_cat(sb, "double VRT_r_now(struct sess *);\n");
}
# Request paramters
{ req.request
- RO STRING
+ RW STRING
{recv pipe pass hash miss hit fetch }
}
{ req.url
- RO STRING
+ RW STRING
{recv pipe pass hash miss hit fetch }
}
{ req.proto
- RO STRING
+ RW STRING
{recv pipe pass hash miss hit fetch }
}
{ req.http.
}
if {$a == "WO" || $a == "RW"} {
puts $fo "\t \"VRT_l_${m}($pa, \","
- if {$t != "HEADER"} {
+ if {$t == "HEADER"} {
+ } elseif {$t == "STRING"} {
+ puts $fp "void VRT_l_${m}($ty, $tt($t), ...);"
+ } else {
puts $fp "void VRT_l_${m}($ty, $tt($t));"
}
} else {
},
{ "req.request", STRING, 11,
"VRT_r_req_request(sp)",
- NULL,
- V_RO,
+ "VRT_l_req_request(sp, ",
+ V_RW,
0,
VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH
},
{ "req.url", STRING, 7,
"VRT_r_req_url(sp)",
- NULL,
- V_RO,
+ "VRT_l_req_url(sp, ",
+ V_RW,
0,
VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH
},
{ "req.proto", STRING, 9,
"VRT_r_req_proto(sp)",
- NULL,
- V_RO,
+ "VRT_l_req_proto(sp, ",
+ V_RW,
0,
VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH
},