From: rousskov <> Date: Mon, 9 Mar 1998 04:03:01 +0000 (+0000) Subject: Initial revision. X-Git-Tag: SQUID_3_0_PRE1~3870 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7c887d1fe9c49631eae9b48a06acf83ce9ae0146;p=thirdparty%2Fsquid.git Initial revision. --- diff --git a/src/HttpHdrContRange.cc b/src/HttpHdrContRange.cc new file mode 100644 index 0000000000..ab835e2007 --- /dev/null +++ b/src/HttpHdrContRange.cc @@ -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); +}