*/
#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
#include <ctype.h>
#include "libvarnish.h"
void
HttpdAnalyze(struct sess *sp)
{
- const char *p, *q;
+ char *p, *q, *r;
sp->handling = HND_Unclass;
/* First, isolate and possibly identify request type */
- p = sp->req_b = sp->rcv;
- for (q = p; isalpha(*q); q++)
+ sp->req_b = sp->rcv;
+ for (p = sp->rcv; isalpha(*p); p++)
;
- p = sp->req_e = q;
- VSLR(SLT_Request, sp->fd, sp->req_b, sp->req_e);
+ VSLR(SLT_Request, sp->fd, sp->req_b, p);
+ *p++ = '\0';
/* Next find the URI */
while (isspace(*p))
sp->url_b = p;
while (!isspace(*p))
p++;
- sp->url_e = p;
- VSLR(SLT_URL, sp->fd, sp->url_b, sp->url_e);
+ VSLR(SLT_URL, sp->fd, sp->url_b, p);
+ *p++ = '\0';
/* Finally, look for protocol, if any */
while (isspace(*p) && *p != '\n')
p++;
- sp->proto_b = sp->proto_e = p;
+ sp->proto_b = p;
if (*p != '\n') {
while (!isspace(*p))
p++;
- sp->proto_e = p;
}
- VSLR(SLT_Protocol, sp->fd, sp->proto_b, sp->proto_e);
+ VSLR(SLT_Protocol, sp->fd, sp->proto_b, p);
+ *p++ = '\0';
- /*
- * And mark the start of headers. The end of headers
- * is already set in acceptor where we detected the complete request.
- */
- while (*p != '\n')
+ while (isspace(*p) && *p != '\n')
p++;
+
p++;
- while (isspace(*p) && *p != '\n')
+ if (*p == '\r')
p++;
- sp->hdr_b = p;
- VSLR(SLT_Headers, sp->fd, sp->hdr_b, sp->hdr_e);
+
+#define HTTPH(a, b) sp->b = NULL;
+#include "http_headers.h"
+#undef HTTPH
+
+ for (; p < sp->rcv + sp->rcv_len; p = r) {
+ q = strchr(p, '\n');
+ r = q + 1;
+ if (q > p && q[-1] == '\r')
+ q--;
+ *q = '\0';
+ if (p == q)
+ break;
+
+#define W(a, b, p, q, sp) \
+ if (!strncasecmp(p, a, strlen(a))) { \
+ for (p += strlen(a); p < q && isspace(*p); p++) \
+ continue; \
+ sp->b = p; \
+ VSLR(SLT_##b, sp->fd, p, q); \
+ continue; \
+ }
+
+#define HTTPH(a, b) W(a ":", b, p, q, sp)
+#include "http_headers.h"
+#undef HTTPH
+#undef W
+ VSLR(SLT_H_Unknown, sp->fd, p, q);
+ }
+
}
fputs(" * XXX: *MUST* be rerun.\n", f);
fputs(" */\n", f);
fputs("\n", f);
+ fputs("/* XXX: This include is bad. The VCL compiler shouldn't know about it. */\n", f);
fputs("#include <sys/queue.h>\n", f);
- fputs("#include <pthread.h>\n", f);
fputs("\n", f);
fputs("struct vcl_ref {\n", f);
fputs(" unsigned line;\n", f);
fputs("\n", f);
fputs(" /* HTTP request info, points into rcv */\n", f);
fputs(" const char *req_b;\n", f);
- fputs(" const char *req_e;\n", f);
fputs(" const char *url_b;\n", f);
- fputs(" const char *url_e;\n", f);
fputs(" const char *proto_b;\n", f);
- fputs(" const char *proto_e;\n", f);
- fputs(" const char *hdr_b;\n", f);
- fputs(" const char *hdr_e;\n", f);
+ fputs("#define HTTPH(a, b) const char *b;\n", f);
+ fputs("/*\n", f);
+ fputs(" * $Id$\n", f);
+ fputs(" */\n", f);
+ fputs("\n", f);
+ fputs("HTTPH(\"Accept-Charset\", H_Accept_Charset)\n", f);
+ fputs("HTTPH(\"Accept-Encoding\", H_Accept_Encoding)\n", f);
+ fputs("HTTPH(\"Accept-Language\", H_Accept_Language)\n", f);
+ fputs("HTTPH(\"Accept\", H_Accept)\n", f);
+ fputs("HTTPH(\"Authorization\", H_Authorization)\n", f);
+ fputs("HTTPH(\"Connection\", H_Connection)\n", f);
+ fputs("HTTPH(\"Expect\", H_Expect)\n", f);
+ fputs("HTTPH(\"From\", H_From)\n", f);
+ fputs("HTTPH(\"Host\", H_Host)\n", f);
+ fputs("HTTPH(\"If-Match\", H_If_Match)\n", f);
+ fputs("HTTPH(\"If-Modified-Since\", H_If_Modified_Since)\n", f);
+ fputs("HTTPH(\"If-None-Match\", H_If_None_Match)\n", f);
+ fputs("HTTPH(\"If-Range\", H_If_Range)\n", f);
+ fputs("HTTPH(\"If-Unmodified-Since\", H_If_Unmodifed_Since)\n", f);
+ fputs("HTTPH(\"Keep-Alive\", H_Keep_Alive)\n", f);
+ fputs("HTTPH(\"Max-Forwards\", H_Max_Forwards)\n", f);
+ fputs("HTTPH(\"Proxy-Authorization\", H_Proxy_Authorization)\n", f);
+ fputs("HTTPH(\"Range\", H_Range)\n", f);
+ fputs("HTTPH(\"Referer\", H_Referer)\n", f);
+ fputs("HTTPH(\"TE\", H_TE)\n", f);
+ fputs("HTTPH(\"User-Agent\", H_User_Agent)\n", f);
+ fputs("#undef HTTPH\n", f);
fputs("\n", f);
fputs(" enum {\n", f);
fputs(" HND_Unclass,\n", f);