Commit 85a93248 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Refuse all requests without a protocol field with a 400

Implement a function to say "400" with.



git-svn-id: http://www.varnish-cache.org/svn/trunk@360 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 183f3ca1
......@@ -182,7 +182,7 @@ int http_HdrIs(struct http *hp, const char *hdr, const char *val);
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,
......@@ -217,6 +217,9 @@ void VSL(enum shmlogtag tag, unsigned id, const char *fmt, ...);
#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);
......
......@@ -265,7 +265,7 @@ FetchSession(struct worker *w, struct sess *sp)
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);
......
......@@ -205,7 +205,7 @@ http_GetStatus(struct http *hp)
/*--------------------------------------------------------------------*/
void
int
http_Dissect(struct http *hp, int fd, int rr)
{
char *p, *q, *r;
......@@ -216,7 +216,7 @@ http_Dissect(struct http *hp, int fd, int rr)
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++)
;
......@@ -224,31 +224,34 @@ http_Dissect(struct http *hp, int fd, int rr)
*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;
......@@ -304,6 +307,7 @@ http_Dissect(struct http *hp, int fd, int rr)
if (hp->t != r)
printf("hp->t %p r %p\n", hp->t, r);
assert(hp->t == r);
return (0);
}
/*--------------------------------------------------------------------*/
......@@ -390,6 +394,7 @@ http_RecvHead(struct http *hp, int fd, struct event_base *eb, http_callback_f *f
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;
......@@ -460,21 +465,15 @@ http_BuildSbuf(int fd, enum http_build mode, struct sbuf *sb, struct http *hp)
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:
......
......@@ -84,7 +84,11 @@ CacheWorker(void *priv)
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];
......@@ -121,6 +125,7 @@ CacheWorker(void *priv)
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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment