📄 httphdrcontrange.c
字号:
/* * $Id: HttpHdrContRange.c,v 1.10 1998/12/05 00:54:09 wessels 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. Squid is Copyrighted (C) 1998 by * Duane Wessels and the University of California San Diego. Please * see the COPYRIGHT file for full details. Squid incorporates * software developed and/or copyrighted by other sources. Please see * the CREDITS file for full details. * * 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., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"/* * 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 *//* 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 inthttpHdrRangeRespSpecParseInit(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 1; /* check format, must be %d-%d */ if (!((p = strchr(field, '-')) && (p - field < flen))) { debug(68, 2) ("invalid (no '-') resp-range-spec near: '%s'\n", field); return 0; } /* parse offset */ if (!httpHeaderParseSize(field, &spec->offset)) return 0; 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 + 1, spec->offset); } /* we managed to parse, check if the result makes sence */ if (known_spec(spec->length) && !spec->length) { debug(68, 2) ("invalid range (%d += %d) in resp-range-spec near: '%s'\n", spec->offset, spec->length, field); return 0; } return 1;}static voidhttpHdrRangeRespSpecPackInto(const HttpHdrRangeSpec * spec, Packer * p){ if (!known_spec(spec->offset) || !known_spec(spec->length)) packerPrintf(p, "*"); else packerPrintf(p, "bytes %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 */inthttpHdrContRangeParseInit(HttpHdrContRange * range, const char *str){ const char *p; assert(range && str); debug(68, 8) ("parsing content-range field: '%s'\n", str); /* check range type */ if (strncasecmp(str, "bytes ", 6)) return 0; str += 6; /* 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; debug(68, 8) ("parsed content-range field: %d-%d / %d\n", range->spec.offset, range->spec.offset + range->spec.length - 1, range->elength); return 1;}voidhttpHdrContRangeDestroy(HttpHdrContRange * range){ assert(range); memFree(range, MEM_HTTP_HDR_CONTENT_RANGE);}HttpHdrContRange *httpHdrContRangeDup(const HttpHdrContRange * range){ HttpHdrContRange *dup; assert(range); dup = httpHdrContRangeCreate(); *dup = *range; return dup;}voidhttpHdrContRangePackInto(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);}voidhttpHdrContRangeSet(HttpHdrContRange * cr, HttpHdrRangeSpec spec, size_t ent_len){ assert(cr && ent_len >= 0); cr->spec = spec; cr->elength = ent_len;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -