]> err.no Git - varnish/commitdiff
Refuse all requests without a protocol field with a 400
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 6 Jul 2006 21:47:51 +0000 (21:47 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 6 Jul 2006 21:47:51 +0000 (21:47 +0000)
Implement a function to say "400" with.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@360 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_http.c
varnish-cache/bin/varnishd/cache_pool.c
varnish-cache/bin/varnishd/cache_response.c

index ac6995534849606887e1f344fc71c0a9a66c3af3..e3083ca948dda343c693726731a0d4a42fb8ab49 100644 (file)
@@ -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);
index 685b7483e089462759f653309d20104275a42fcc..6055259abf1d82596c5c81d43d13a08f39d7e190 100644 (file)
@@ -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);
 
index f5ea906518205fe335cb2a42f3d661c3d27e700b..795d4c126080d20fd17c66d7908f0275fa94b083 100644 (file)
@@ -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:
index 78dfb50a9d125f8e775507475722b00daba3f6db..a8826b1f80fb6114bb051dcb4da0472476fcad1d 100644 (file)
@@ -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;
index ea3664fd54ee266ab04e8df2c0a18cacd1ef15bc..3d250c6941be8dfb843e50da9a788aba082b6631 100644 (file)
@@ -1,3 +1,57 @@
 /*
  * $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);
+}