1 /* 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors 3 * 4 * Squid software is distributed under GPLv2+ license and includes 5 * contributions from numerous individuals and organizations. 6 * Please see the COPYING and CONTRIBUTORS files for details. 7 */ 8 9 #ifndef SQUID_HTTPHEADERRANGE_H 10 #define SQUID_HTTPHEADERRANGE_H 11 12 #include "mem/forward.h" 13 #include "Range.h" 14 #include "SquidString.h" 15 16 #include <vector> 17 18 class HttpReply; 19 class Packable; 20 21 // TODO: Refactor to disambiguate and provide message-specific APIs. 22 /// either byte-range-spec (in a request Range header) 23 /// or suffix-byte-range-spec (in a request Range header) 24 /// or byte-range part of byte-range-resp (in a response Content-Range header) 25 /// or "*" part of unsatisfied-range (in a response Content-Range header) 26 class HttpHdrRangeSpec 27 { 28 MEMPROXY_CLASS(HttpHdrRangeSpec); 29 30 public: 31 typedef Range<int64_t, uint64_t> HttpRange; 32 static int64_t const UnknownPosition; 33 34 HttpHdrRangeSpec(); 35 static HttpHdrRangeSpec *Create(const char *field, int fieldLen); 36 37 bool parseInit(const char *field, int flen); 38 int canonize(int64_t clen); 39 void outputInfo( char const *note) const; 40 void packInto(Packable * p) const; 41 bool mergeWith(const HttpHdrRangeSpec * donor); 42 int64_t offset; 43 int64_t length; 44 }; 45 46 /** 47 * There may be more than one byte range specified in the request. 48 * This object holds all range specs in order of their appearence 49 * in the request because we SHOULD preserve that order. 50 */ 51 class HttpHdrRange 52 { 53 MEMPROXY_CLASS(HttpHdrRange); 54 55 public: 56 static size_t ParsedCount; 57 /* Http Range Header Field */ 58 static HttpHdrRange *ParseCreate(const String * range_spec); 59 60 HttpHdrRange(); 61 HttpHdrRange(HttpHdrRange const &); 62 ~HttpHdrRange(); 63 HttpHdrRange &operator= (HttpHdrRange const &); 64 65 typedef std::vector<HttpHdrRangeSpec *>::iterator iterator; 66 typedef std::vector<HttpHdrRangeSpec *>::const_iterator const_iterator; 67 iterator begin(); 68 const_iterator begin () const; 69 iterator end(); 70 const_iterator end() const; 71 72 /* adjust specs after the length is known */ 73 int canonize(int64_t); 74 int canonize(HttpReply *rep); 75 /* returns true if ranges are valid; inits HttpHdrRange */ 76 bool parseInit(const String * range_spec); 77 void packInto(Packable * p) const; 78 /* other */ 79 bool isComplex() const; 80 bool willBeComplex() const; 81 int64_t firstOffset() const; 82 int64_t lowestOffset(int64_t) const; 83 bool offsetLimitExceeded(const int64_t limit) const; 84 std::vector<HttpHdrRangeSpec *> specs; 85 86 private: 87 void getCanonizedSpecs (std::vector<HttpHdrRangeSpec *> ©); 88 void merge (std::vector<HttpHdrRangeSpec *> &basis); 89 int64_t clen; 90 }; 91 92 /** 93 * Data for iterating thru range specs 94 */ 95 class HttpHdrRangeIter 96 { 97 98 public: 99 HttpHdrRange::iterator pos; 100 HttpHdrRange::iterator end; 101 const HttpHdrRangeSpec *currentSpec() const; 102 void updateSpec(); 103 int64_t debt() const; 104 void debt(int64_t); 105 int64_t debt_size = 0; /* bytes left to send from the current spec */ 106 String boundary; /* boundary for multipart responses */ 107 bool valid = false; 108 }; 109 110 #endif /* SQUID_HTTPHEADERRANGE_H */ 111 112