int http_GetTail(struct http *hp, unsigned len, char **b, char **e);
int http_GetURL(struct http *hp, char **b);
void http_RecvHead(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg);
-void http_Dissect(struct http *sp, int fd, int rr);
+int http_Dissect(struct http *sp, int fd, int rr);
enum http_build {
Build_Pipe,
Build_Pass,
#endif
extern struct varnish_stats *VSL_stats;
+/* cache_response.c */
+void RES_Error(struct worker *w, struct sess *sp, int error, const char *msg);
+
/* cache_vcl.c */
void RelVCL(struct VCL_conf *vc);
struct VCL_conf *GetVCL(void);
http_RecvHead(hp, fd, w->eb, NULL, NULL);
event_base_loop(w->eb, 0);
time(&sp->t_resp);
- http_Dissect(hp, fd, 2);
+ assert(http_Dissect(hp, fd, 2) == 0);
body = RFC2616_cache_policy(sp, hp);
/*--------------------------------------------------------------------*/
-void
+int
http_Dissect(struct http *hp, int fd, int rr)
{
char *p, *q, *r;
for (p = hp->s ; isspace(*p); p++)
continue;
if (rr == 1) {
- /* First, isolate and possibly identify request type */
+ /* First, the request type (GET/HEAD etc) */
hp->req = p;
for (; isalpha(*p); p++)
;
*p++ = '\0';
/* Next find the URI */
- while (isspace(*p))
+ while (isspace(*p) && *p != '\n')
p++;
+ if (*p == '\n')
+ return (400);
hp->url = p;
while (!isspace(*p))
p++;
VSLR(SLT_URL, fd, hp->url, p);
- if (*p != '\n') {
- *p++ = '\0';
+ if (*p == '\n')
+ return (400);
+ *p++ = '\0';
- /* Finally, look for protocol, if any */
- while (isspace(*p) && *p != '\n')
- p++;
- if (*p != '\n') {
- hp->proto = p;
- while (!isspace(*p))
- p++;
- if (*p != '\n')
- *p++ = '\0';
- while (isspace(*p) && *p != '\n')
- p++;
- }
- }
+ /* Finally, look for protocol */
+ while (isspace(*p) && *p != '\n')
+ p++;
+ if (*p == '\n')
+ return (400);
+ hp->proto = p;
+ while (!isspace(*p))
+ p++;
+ VSLR(SLT_Protocol, fd, hp->proto, p);
+ if (*p != '\n')
+ *p++ = '\0';
+ while (isspace(*p) && *p != '\n')
+ p++;
+ if (*p != '\n')
+ return (400);
*p++ = '\0';
- if (hp->proto != NULL)
- VSLR(SLT_Protocol, fd, hp->proto, p);
} else {
/* First, protocol */
hp->proto = p;
if (hp->t != r)
printf("hp->t %p r %p\n", hp->t, r);
assert(hp->t == r);
+ return (0);
}
/*--------------------------------------------------------------------*/
assert(hp != NULL);
assert(hp->v <= hp->e);
assert(hp->t <= hp->v);
+ if (0)
VSL(SLT_Debug, fd, "Recv t %u v %u", hp->t - hp->s, hp->v - hp->s);
if (hp->t > hp->s && hp->t < hp->v) {
l = hp->v - hp->t;
sbuf_cat(sb, hp->req);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->url);
- if (hp->proto != NULL) {
- sbuf_cat(sb, " ");
- sbuf_cat(sb, hp->proto);
- }
+ sbuf_cat(sb, " ");
+ sbuf_cat(sb, hp->proto);
sup = 2;
break;
case Build_Fetch:
sbuf_cat(sb, "GET ");
sbuf_cat(sb, hp->url);
- if (hp->proto != NULL) {
- sbuf_cat(sb, " ");
- sbuf_cat(sb, hp->proto);
- } else {
- sbuf_cat(sb, " HTTP/1.1");
- }
+ sbuf_cat(sb, " ");
+ sbuf_cat(sb, hp->proto);
sup = 1;
break;
default:
sp->vcl = GetVCL();
AZ(pthread_mutex_unlock(&sessmtx));
- http_Dissect(sp->http, sp->fd, 1);
+ done = http_Dissect(sp->http, sp->fd, 1);
+ if (done != 0) {
+ RES_Error(&w, sp, done, NULL);
+ goto out;
+ }
sp->backend = sp->vcl->backend[0];
vca_close_session(sp, "not HTTP/1.1");
}
+out:
AZ(pthread_mutex_lock(&sessmtx));
RelVCL(sp->vcl);
sp->vcl = NULL;
/*
* $Id$
*/
+
+#include <stdio.h> /* XXX: for NULL ?? */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <event.h>
+
+#include "libvarnish.h"
+#include "sbuf.h"
+#include "cache.h"
+
+
+/*--------------------------------------------------------------------*/
+
+void
+RES_Error(struct worker *w, struct sess *sp, int error, const char *msg)
+{
+ char buf[40];
+
+ if (msg == NULL) {
+ switch (error) {
+ case 400: msg = "Bad Request"; break;
+ default: msg = "HTTP request error"; break;
+ }
+ }
+
+ sbuf_clear(w->sb);
+ sbuf_printf(w->sb, "HTTP/1.1 %03d %s\r\n", error, msg);
+ TIM_format(sp->t_req, buf);
+ sbuf_printf(w->sb, "Date: %s\r\n", buf);
+ sbuf_cat(w->sb,
+ "Server: Varnish\r\n"
+ "Connection: close\r\n"
+ "content-Type: text/html; charset=iso-8859-1\r\n"
+ "\r\n"
+ "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
+ "<HTML>\r\n"
+ " <HEAD>\r\n");
+ sbuf_printf(w->sb, " <TITLE>%03d %s</TITLE>\r\n", error, msg);
+ sbuf_cat(w->sb,
+ " </HEAD>\r\n"
+ " <BODY>\r\n");
+ sbuf_printf(w->sb, " <H1>Error %03d %s</H1>\r\n", error, msg);
+ sbuf_cat(w->sb,
+ " Your HTTP protocol request did not make sense.\r\n"
+ " <P>\r\n"
+ " <I>\r\n"
+ " <A href=\"http://varnish.linpro.no/\">Varnish</A>\r\n"
+ " </BODY>\r\n"
+ "</HTML>\r\n");
+ sbuf_finish(w->sb);
+ vca_write(sp, sbuf_data(w->sb), sbuf_len(w->sb));
+ vca_flush(sp);
+ vca_close_session(sp, msg);
+}