int http_DissectResponse(struct worker *w, struct http *sp, int fd);
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);
#define HTTPH(a, b, c, d, e, f, g) extern char b[];
static int
-http_IsHdr(struct http_hdr *hh, char *hdr)
+http_IsHdr(struct http_hdr *hh, const char *hdr)
{
unsigned l;
to->nhd++;
}
}
+/*--------------------------------------------------------------------*/
+
+void
+http_Unset(struct http *hp, const char *hdr)
+{
+ unsigned u, v;
+
+ for (v = u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
+ if (http_IsHdr(&hp->hd[u], hdr))
+ continue;
+ if (v != u)
+ memcpy(&hp->hd[v], &hp->hd[u], sizeof hp->hd[v]);
+ v++;
+ }
+ hp->nhd = v;
+}
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <stdarg.h>
#include "shmlog.h"
#include "heritage.h"
/*--------------------------------------------------------------------*/
-char *
-VRT_GetHdr(struct sess *sp, enum gethdr_e where, const char *n)
+static struct http *
+vrt_selecthttp(struct sess *sp, enum gethdr_e where)
{
- char *p;
struct http *hp;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
INCOMPL();
}
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+ return (hp);
+}
+
+char *
+VRT_GetHdr(struct sess *sp, enum gethdr_e where, const char *n)
+{
+ char *p;
+ struct http *hp;
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ hp = vrt_selecthttp(sp, where);
if (!http_GetHdr(hp, n, &p))
return (NULL);
return (p);
/*--------------------------------------------------------------------*/
+void
+VRT_SetHdr(struct sess *sp , enum gethdr_e where, const char *hdr, ...)
+{
+ struct http *hp;
+ va_list ap;
+ const char *p;
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ hp = vrt_selecthttp(sp, where);
+ va_start(ap, hdr);
+ p = va_arg(ap, const char *);
+ if (p == NULL) {
+ http_Unset(hp, hdr);
+ } else {
+ INCOMPL();
+ }
+ va_end(ap);
+}
+
+/*--------------------------------------------------------------------*/
+
void
VRT_handling(struct sess *sp, unsigned hand)
{
enum gethdr_e { HDR_REQ, HDR_RESP, HDR_OBJ, HDR_BEREQ };
char *VRT_GetHdr(struct sess *, enum gethdr_e where, const char *);
+void VRT_SetHdr(struct sess *, enum gethdr_e where, const char *, ...);
void VRT_handling(struct sess *sp, unsigned hand);
/* Backend related */
" only '=' is legal for %s\n", type);
}
+static void
+check_writebit(struct tokenlist *tl, struct var *vp)
+{
+
+ if (vp->access == V_RW || vp->access == V_WO)
+ return;
+ vsb_printf(tl->sb, "Variable %.*s cannot be modified.\n", PF(tl->t));
+ vcc_ErrWhere(tl, tl->t);
+}
+
static void
parse_set(struct tokenlist *tl)
{
vp = vcc_FindVar(tl, tl->t, vcc_vars);
ERRCHK(tl);
assert(vp != NULL);
- if (vp->access != V_RW && vp->access != V_WO) {
- vsb_printf(tl->sb, "Variable %.*s cannot be written.\n",
- PF(vt));
- vcc_ErrWhere(tl, vt);
- return;
- }
+ check_writebit(tl, vp);
+ ERRCHK(tl);
Fb(tl, 1, "%s", vp->lname);
vcc_NextToken(tl);
switch (vp->fmt) {
/*--------------------------------------------------------------------*/
+static void
+parse_remove(struct tokenlist *tl)
+{
+ struct var *vp;
+ struct token *vt;
+
+ vcc_NextToken(tl);
+ ExpectErr(tl, VAR);
+ vt = tl->t;
+ vp = vcc_FindVar(tl, tl->t, vcc_vars);
+ if (vp->fmt != STRING) {
+ vsb_printf(tl->sb,
+ "Only STRING variables can be removed.\n");
+ vcc_ErrWhere(tl, tl->t);
+ return;
+ }
+ check_writebit(tl, vp);
+ ERRCHK(tl);
+ Fb(tl, 1, "%s, 0);\n", vp->lname);
+ vcc_NextToken(tl);
+ ExpectErr(tl, ';');
+}
+
+/*--------------------------------------------------------------------*/
+
typedef void action_f(struct tokenlist *tl);
static struct action_table {
#undef VCL_RET_MAC_E
{ "call", parse_call },
{ "set", parse_set },
+ { "remove", parse_remove },
{ NULL, NULL }
};
vsb_cat(sb, "\n");
vsb_cat(sb, "enum gethdr_e { HDR_REQ, HDR_RESP, HDR_OBJ, HDR_BEREQ };\n");
vsb_cat(sb, "char *VRT_GetHdr(struct sess *, enum gethdr_e where, const char *);\n");
+ vsb_cat(sb, "void VRT_SetHdr(struct sess *, enum gethdr_e where, const char *, ...);\n");
vsb_cat(sb, "void VRT_handling(struct sess *sp, unsigned hand);\n");
vsb_cat(sb, "\n");
vsb_cat(sb, "/* Backend related */\n");
(unsigned)(strlen(v->name + vh->len) + 1), v->name + vh->len);
AN(p);
v->rname = p;
- asprintf(&p, "VRT_SetHdr(sp, %s, \"\\%03o%s:\")", wh,
+ asprintf(&p, "VRT_SetHdr(sp, %s, \"\\%03o%s:\"", wh,
(unsigned)(strlen(v->name + vh->len) + 1), v->name + vh->len);
AN(p);
v->lname = p;