]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Initial revision.
authorrousskov <>
Mon, 9 Mar 1998 04:03:01 +0000 (04:03 +0000)
committerrousskov <>
Mon, 9 Mar 1998 04:03:01 +0000 (04:03 +0000)
src/HttpHdrContRange.cc [new file with mode: 0644]

diff --git a/src/HttpHdrContRange.cc b/src/HttpHdrContRange.cc
new file mode 100644 (file)
index 0000000..ab835e2
--- /dev/null
@@ -0,0 +1,176 @@
+
+/*
+ * $Id: HttpHdrContRange.cc,v 1.1 1998/03/08 21:03:01 rousskov Exp $
+ *
+ * DEBUG: section 68    HTTP Content-Range Header
+ * AUTHOR: Alex Rousskov
+ *
+ * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
+ * --------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from the
+ *  Internet community.  Development is led by Duane Wessels of the
+ *  National Laboratory for Applied Network Research and funded by
+ *  the National Science Foundation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  
+ */
+
+#include "squid.h"
+
+#if 0
+    Currently only byte ranges are supported
+
+    Content-Range = "Content-Range" ":" content-range-spec
+    content-range-spec      = byte-content-range-spec
+    byte-content-range-spec = bytes-unit SP
+                              ( byte-range-resp-spec | "*") "/"
+                              ( entity-length | "*" )
+    byte-range-resp-spec = first-byte-pos "-" last-byte-pos
+    entity-length        = 1*DIGIT
+#endif
+
+
+/* local constants */
+#define range_spec_unknown ((size_t)-1)
+
+/* local routines */
+#define known_spec(s) ((s) != range_spec_unknown)
+#define size_min(a,b) ((a) <= (b) ? (a) : (b))
+#define size_diff(a,b) ((a) >= (b) ? ((a)-(b)) : 0)
+
+/* globals */
+
+/* parses range-resp-spec and inits spec, returns true on success */
+static int
+httpHdrRangeRespSpecParseInit(HttpHdrRangeSpec *spec, const char *field, int flen)
+{
+    const char *p;
+    assert(spec);
+    spec->offset = spec->length = range_spec_unknown;
+    if (flen < 2)
+       return 0;
+    /* is spec given ? */
+    if (*field == '*')
+       return 0;
+    /* check format, must be %d-%d */
+    if (!((p = strchr(field, '-')) && (p-field < flen))) {
+       debug(68, 2) ("invalid resp-range-spec near: '%s'\n", field);
+       return 0;
+    }
+    /* parse offset */
+    if (!httpHeaderParseSize(field+1, &spec->offset))
+           return NULL;
+    p++;
+    /* do we have last-pos ? */
+    if (p - field < flen) {
+       size_t last_pos;
+       if (!httpHeaderParseSize(p, &last_pos))
+           return 0;
+       spec->length = size_diff(last_pos, spec->offset);
+    }
+    /* we managed to parse, check if the result makes sence */
+    if (known_spec(spec->length) && !spec->length) {
+       debug(68, 2) ("invalid resp-range-spec near: '%s'\n", field);
+       return 0;
+    }
+    return 1;
+}
+
+static void
+httpHdrRangeRespSpecPackInto(const HttpHdrRangeSpec *spec, Packer *p)
+{
+    if (!known_spec(spec->offset) || !known_spec(spec->length))
+       packerPrintf(p, "*");
+    else
+       packerPrintf(p, "%d-%d", 
+           spec->offset, spec->offset+spec->length-1);
+}
+
+/*
+ * Content Range
+ */
+
+HttpHdrContRange *
+httpHdrContRangeCreate()
+{
+    HttpHdrContRange *r = memAllocate(MEM_HTTP_HDR_CONTENT_RANGE);
+    r->spec.offset = r->spec.length = range_spec_unknown;
+    r->elength = range_spec_unknown;
+    return r;
+}
+
+HttpHdrContRange *
+httpHdrContRangeParseCreate(const char *str)
+{
+    HttpHdrContRange *r = httpHdrContRangeCreate();
+    if (!httpHdrContRangeParseInit(r, str)) {
+       httpHdrContRangeDestroy(r);
+       r = NULL;
+    }
+    return r;
+}
+
+/* returns true if ranges are valid; inits HttpHdrContRange */
+int
+httpHdrContRangeParseInit(HttpHdrContRange *range, const char *str)
+{
+    const char *p;
+    assert(range && str);
+    /* split */
+    if (!(p = strchr(str, '/')))
+       return 0;
+    if (*str == '*')
+       range->spec.offset = range->spec.length = range_spec_unknown;
+    else
+    if (!httpHdrRangeRespSpecParseInit(&range->spec, str, p-str))
+       return 0;
+    p++;
+    if (*p == '*')
+       range->elength = range_spec_unknown;
+    else
+    if (!httpHeaderParseSize(p, &range->elength))
+       return 0;
+    return 1;
+}
+
+void
+httpHdrContRangeDestroy(HttpHdrContRange *range)
+{
+    assert(range);
+    memFree(MEM_HTTP_HDR_CONTENT_RANGE, range);
+}
+
+HttpHdrContRange *
+httpHdrContRangeDup(const HttpHdrContRange * range)
+{
+    HttpHdrContRange *dup;
+    assert(range);
+    dup = httpHdrContRangeCreate();
+    *dup = *range;
+    return dup;
+}
+
+void
+httpHdrContRangePackInto(const HttpHdrContRange * range, Packer * p)
+{
+    assert(range && p);
+    httpHdrRangeRespSpecPackInto(&range->spec, p);
+    if (!known_spec(range->elength))
+       packerPrintf(p, "/*");
+    else
+       packerPrintf(p, "/%d", range->elength);
+}