]> err.no Git - varnish/commitdiff
Initial split of code which transfer HTTP protocol messages
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 28 Sep 2007 13:13:11 +0000 (13:13 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 28 Sep 2007 13:13:11 +0000 (13:13 +0000)
over sockets and things which manipulate them in memory.

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

varnish-cache/bin/varnishd/Makefile.am
varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_http.c
varnish-cache/bin/varnishd/cache_httpconn.c [new file with mode: 0644]

index a2b0b8492a8419e21e161a0e8fedd044a1813873..6752e79385c72383e06ba3b0818151e35cd7f970 100644 (file)
@@ -22,6 +22,7 @@ varnishd_SOURCES = \
        cache_fetch.c \
        cache_hash.c \
        cache_http.c \
+       cache_httpconn.c \
        cache_main.c \
        cache_pool.c \
        cache_pipe.c \
index eb6c7ba281dcf609e57d4c8f678ecbfc57ee25e9..a6eb0d35345569719803ee77e8e83dc735e0db94 100644 (file)
@@ -122,6 +122,16 @@ struct http {
        unsigned                nhd;
 };
 
+struct http_conn {
+       unsigned                magic;
+#define HTTP_CONN_MAGIC                0x3e19edd1
+
+       struct http             *http;
+       struct ws               *ws;
+       txt                     rxbuf;
+       txt                     pipeline;
+};
+
 /*--------------------------------------------------------------------*/
 
 struct acct {
index 01cd3bc57140ce6902c68d67c43fcf476c0efd7f..f570b91a35a85adaf58c66bda9aec31f968b5cf4 100644 (file)
@@ -316,60 +316,6 @@ http_HdrIs(const struct http *hp, const char *hdr, const char *val)
 
 /*--------------------------------------------------------------------*/
 
-int
-http_GetTail(struct http *hp, unsigned len, char **b, char **e)
-{
-
-       if (hp->pl.b >= hp->pl.e)
-               return (0);
-
-       if (len == 0)
-               len = Tlen(hp->pl);
-
-       if (hp->pl.b + len > hp->pl.e)
-               len = Tlen(hp->pl);
-       if (len == 0)
-               return (0);
-       *b = hp->pl.b;
-       *e = hp->pl.b + len;
-       hp->pl.b += len;
-       Tcheck(hp->pl);
-       return (1);
-}
-
-/*--------------------------------------------------------------------*/
-/* Read from fd, but soak up any tail first */
-
-int
-http_Read(struct http *hp, int fd, void *p, unsigned len)
-{
-       int i;
-       unsigned u;
-       char *b = p;
-
-       u = 0;
-       if (hp->pl.b < hp->pl.e) {
-               u = Tlen(hp->pl);
-               if (u > len)
-                       u = len;
-               memcpy(b, hp->pl.b, u);
-               hp->pl.b += u;
-               b += u;
-               len -= u;
-       }
-       if (hp->pl.e == hp->pl.b)
-               hp->pl.b = hp->pl.e = NULL;
-       if (len > 0) {
-               i = read(fd, b, len);
-               if (i < 0)              /* XXX i == 0 ?? */
-                       return (i);
-               u += i;
-       }
-       return (u);
-}
-
-/*--------------------------------------------------------------------*/
-
 int
 http_GetStatus(const struct http *hp)
 {
@@ -561,154 +507,6 @@ http_DissectResponse(struct worker *w, struct http *hp, int fd)
 
        return (http_dissect_hdrs(w, hp, fd, p));
 }
-
-/*--------------------------------------------------------------------
- * Check if we have a complete HTTP request or response yet between the
- * two pointers given.
- *
- * Return values:
- *     -1  No, and you can nuke the (white-space) content.
- *      0  No, keep trying
- *     >0  Yes, it is this many bytes long.
- */
-
-static int
-http_header_complete(const char *b, const char *e)
-{
-       const char *p;
-
-       AN(b);
-       AN(e);
-       assert(b <= e);
-       assert(*e == '\0');
-       /* Skip any leading white space */
-       for (p = b ; isspace(*p); p++)
-               continue;
-       if (*p == '\0')
-               return (-1);
-       while (1) {
-               p = strchr(p, '\n');
-               if (p == NULL)
-                       return (0);
-               p++;
-               if (*p == '\r')
-                       p++;
-               if (*p == '\n')
-                       break;
-       }
-       p++;
-       return (p - b);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-http_RecvPrep(struct http *hp)
-{
-       unsigned l;
-
-       CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
-       WS_Assert(hp->ws);
-       WS_Reset(hp->ws);
-       WS_Reserve(hp->ws, 0);
-       hp->rx.b = hp->ws->f;
-       hp->rx.e = hp->rx.b;
-       if (hp->pl.b != NULL) {
-               l = Tlen(hp->pl);
-               memmove(hp->rx.b, hp->pl.b, l);
-               hp->rx.e = hp->rx.b + l;
-               hp->pl.b = hp->pl.e = NULL;
-       }
-       *hp->rx.e = '\0';
-}
-
-int
-http_RecvPrepAgain(struct http *hp)
-{
-       int i;
-
-       http_RecvPrep(hp);
-       if (hp->rx.b == hp->rx.e)
-               return (0);
-       i = http_header_complete(hp->rx.b, hp->rx.e);
-       if (i == -1)
-               hp->rx.e = hp->rx.b;
-       if (i <= 0)
-               return (0);
-       WS_ReleaseP(hp->ws, hp->rx.e);
-       if (hp->rx.e != hp->rx.b + i) {
-               hp->pl.b = hp->rx.b + i;
-               hp->pl.e = hp->rx.e;
-               hp->rx.e = hp->pl.b;
-       }
-       return (i);
-}
-
-/*--------------------------------------------------------------------*/
-
-int
-http_RecvSome(int fd, struct http *hp)
-{
-       unsigned l;
-       int i;
-
-       l = pdiff(hp->rx.e, hp->ws->e) - 1;
-       l /= 2;         /* Don't fill all of workspace with read-ahead */
-       if (l <= 1) {
-               VSL(SLT_HttpError, fd, "Received too much");
-               VSLR(SLT_HttpGarbage, fd, hp->rx);
-               hp->rx.b = hp->rx.e = NULL;
-               WS_Release(hp->ws, 0);
-               return (1);
-       }
-       errno = 0;
-       i = read(fd, hp->rx.e, l - 1);
-       if (i > 0) {
-               hp->rx.e += i;
-               *hp->rx.e = '\0';
-               i = http_header_complete(hp->rx.b, hp->rx.e);
-               if (i == -1)
-                       hp->rx.e = hp->rx.b;
-               if (i == 0)
-                       return (-1);
-               WS_ReleaseP(hp->ws, hp->rx.e);
-               if (hp->rx.e != hp->rx.b + i) {
-                       hp->pl.b = hp->rx.b + i;
-                       hp->pl.e = hp->rx.e;
-                       hp->rx.e = hp->pl.b;
-               }
-               return (0);
-       }
-
-       if (hp->rx.e != hp->rx.b) {
-               VSL(SLT_HttpError, fd,
-                   "Received (only) %d bytes, errno %d",
-                   hp->rx.e - hp->rx.b, errno);
-               VSLR(SLT_Debug, fd, hp->rx);
-       } else if (errno == 0)
-               VSL(SLT_HttpError, fd, "Received nothing");
-       else
-               VSL(SLT_HttpError, fd, "Received errno %d", errno);
-       hp->rx.b = hp->rx.e = NULL;
-       WS_Release(hp->ws, 0);
-       return(2);
-}
-
-/*--------------------------------------------------------------------*/
-
-int
-http_RecvHead(struct http *hp, int fd)
-{
-       int i;
-
-       CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
-       http_RecvPrep(hp);
-       do
-               i = http_RecvSome(fd, hp);
-       while (i == -1);
-       return (i);
-}
-
 /*--------------------------------------------------------------------*/
 
 void
diff --git a/varnish-cache/bin/varnishd/cache_httpconn.c b/varnish-cache/bin/varnishd/cache_httpconn.c
new file mode 100644 (file)
index 0000000..cd39752
--- /dev/null
@@ -0,0 +1,241 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2007 Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: cache_http.c 2052 2007-09-28 11:07:14Z phk $
+ *
+ * HTTP protocol requests
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "shmlog.h"
+#include "cache.h"
+
+/*--------------------------------------------------------------------
+ * Check if we have a complete HTTP request or response yet between the
+ * two pointers given.
+ *
+ * Return values:
+ *     -1  No, and you can nuke the (white-space) content.
+ *      0  No, keep trying
+ *     >0  Yes, it is this many bytes long.
+ */
+
+static int
+http_header_complete(const char *b, const char *e)
+{
+       const char *p;
+
+       AN(b);
+       AN(e);
+       assert(b <= e);
+       assert(*e == '\0');
+       /* Skip any leading white space */
+       for (p = b ; isspace(*p); p++)
+               continue;
+       if (*p == '\0')
+               return (-1);
+       while (1) {
+               p = strchr(p, '\n');
+               if (p == NULL)
+                       return (0);
+               p++;
+               if (*p == '\r')
+                       p++;
+               if (*p == '\n')
+                       break;
+       }
+       p++;
+       return (p - b);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+http_RecvPrep(struct http *hp)
+{
+       unsigned l;
+
+       CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+       WS_Assert(hp->ws);
+       WS_Reset(hp->ws);
+       WS_Reserve(hp->ws, 0);
+       hp->rx.b = hp->ws->f;
+       hp->rx.e = hp->rx.b;
+       if (hp->pl.b != NULL) {
+               l = Tlen(hp->pl);
+               memmove(hp->rx.b, hp->pl.b, l);
+               hp->rx.e = hp->rx.b + l;
+               hp->pl.b = hp->pl.e = NULL;
+       }
+       *hp->rx.e = '\0';
+}
+
+int
+http_RecvPrepAgain(struct http *hp)
+{
+       int i;
+
+       http_RecvPrep(hp);
+       if (hp->rx.b == hp->rx.e)
+               return (0);
+       i = http_header_complete(hp->rx.b, hp->rx.e);
+       if (i == -1)
+               hp->rx.e = hp->rx.b;
+       if (i <= 0)
+               return (0);
+       WS_ReleaseP(hp->ws, hp->rx.e);
+       if (hp->rx.e != hp->rx.b + i) {
+               hp->pl.b = hp->rx.b + i;
+               hp->pl.e = hp->rx.e;
+               hp->rx.e = hp->pl.b;
+       }
+       return (i);
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+http_RecvSome(int fd, struct http *hp)
+{
+       unsigned l;
+       int i;
+
+       l = pdiff(hp->rx.e, hp->ws->e) - 1;
+       l /= 2;         /* Don't fill all of workspace with read-ahead */
+       if (l <= 1) {
+               VSL(SLT_HttpError, fd, "Received too much");
+               VSLR(SLT_HttpGarbage, fd, hp->rx);
+               hp->rx.b = hp->rx.e = NULL;
+               WS_Release(hp->ws, 0);
+               return (1);
+       }
+       errno = 0;
+       i = read(fd, hp->rx.e, l - 1);
+       if (i > 0) {
+               hp->rx.e += i;
+               *hp->rx.e = '\0';
+               i = http_header_complete(hp->rx.b, hp->rx.e);
+               if (i == -1)
+                       hp->rx.e = hp->rx.b;
+               if (i == 0)
+                       return (-1);
+               WS_ReleaseP(hp->ws, hp->rx.e);
+               if (hp->rx.e != hp->rx.b + i) {
+                       hp->pl.b = hp->rx.b + i;
+                       hp->pl.e = hp->rx.e;
+                       hp->rx.e = hp->pl.b;
+               }
+               return (0);
+       }
+
+       if (hp->rx.e != hp->rx.b) {
+               VSL(SLT_HttpError, fd,
+                   "Received (only) %d bytes, errno %d",
+                   hp->rx.e - hp->rx.b, errno);
+               VSLR(SLT_Debug, fd, hp->rx);
+       } else if (errno == 0)
+               VSL(SLT_HttpError, fd, "Received nothing");
+       else
+               VSL(SLT_HttpError, fd, "Received errno %d", errno);
+       hp->rx.b = hp->rx.e = NULL;
+       WS_Release(hp->ws, 0);
+       return(2);
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+http_RecvHead(struct http *hp, int fd)
+{
+       int i;
+
+       CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+       http_RecvPrep(hp);
+       do
+               i = http_RecvSome(fd, hp);
+       while (i == -1);
+       return (i);
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+http_GetTail(struct http *hp, unsigned len, char **b, char **e)
+{
+
+       if (hp->pl.b >= hp->pl.e)
+               return (0);
+
+       if (len == 0)
+               len = Tlen(hp->pl);
+
+       if (hp->pl.b + len > hp->pl.e)
+               len = Tlen(hp->pl);
+       if (len == 0)
+               return (0);
+       *b = hp->pl.b;
+       *e = hp->pl.b + len;
+       hp->pl.b += len;
+       Tcheck(hp->pl);
+       return (1);
+}
+
+/*--------------------------------------------------------------------*/
+/* Read from fd, but soak up any tail first */
+
+int
+http_Read(struct http *hp, int fd, void *p, unsigned len)
+{
+       int i;
+       unsigned u;
+       char *b = p;
+
+       u = 0;
+       if (hp->pl.b < hp->pl.e) {
+               u = Tlen(hp->pl);
+               if (u > len)
+                       u = len;
+               memcpy(b, hp->pl.b, u);
+               hp->pl.b += u;
+               b += u;
+               len -= u;
+       }
+       if (hp->pl.e == hp->pl.b)
+               hp->pl.b = hp->pl.e = NULL;
+       if (len > 0) {
+               i = read(fd, b, len);
+               if (i < 0)              /* XXX i == 0 ?? */
+                       return (i);
+               u += i;
+       }
+       return (u);
+}
+