1 /*
2  * Copyright 2020 Veloman Yunkan <veloman.yunkan@gmail.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU  General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  * MA 02110-1301, USA.
18  */
19 
20 
21 #ifndef KIWIXLIB_SERVER_BYTE_RANGE_H
22 #define KIWIXLIB_SERVER_BYTE_RANGE_H
23 
24 #include <cstdint>
25 #include <string>
26 
27 namespace kiwix {
28 
29 class ByteRange
30 {
31   public: // types
32     // ByteRange is parsed in a request, then it must be resolved (taking
33     // into account the actual size of the requested resource) before
34     // being applied in the response.
35     // The Kind enum represents possible states in such a lifecycle.
36     enum Kind {
37       // The request is not a range request (no Range header)
38       NONE,
39 
40       // The value of the Range header is not a valid continuous
41       // range. Note that a valid (according to RFC7233) sequence of multiple
42       // byte ranges is considered invalid in the current implementation
43       // (i.e. only single-range partial requests are supported).
44       INVALID,
45 
46       // This byte-range has been successfully parsed from the request
47       PARSED,
48 
49       // This is a response to a regular (non-range) request
50       RESOLVED_FULL_CONTENT,
51 
52       // The range request is invalid or unsatisfiable
53       RESOLVED_UNSATISFIABLE,
54 
55       // This is a response to a (satisfiable) range request
56       RESOLVED_PARTIAL_CONTENT,
57     };
58 
59   public: // functions
60     // Constructs a ByteRange object of NONE kind
61     ByteRange();
62 
63     // Constructs a ByteRange object of the given kind (except NONE)
64     ByteRange(Kind kind, int64_t first, int64_t last);
65 
66     // Constructs a ByteRange object of PARSED kind corresponding to a
67     // range request of the form "Range: bytes=-suffix_length"
68     explicit ByteRange(int64_t suffix_length);
69 
kind()70     Kind kind() const { return kind_; }
71     int64_t first() const;
72     int64_t last() const;
73     int64_t length() const;
74 
75     static ByteRange parse(const std::string& rangeStr);
76     ByteRange resolve(int64_t contentSize) const;
77 
78   private: // data
79     Kind kind_;
80     int64_t first_;
81     int64_t last_;
82 };
83 
84 } // namespace kiwix
85 
86 #endif //KIWIXLIB_SERVER_BYTE_RANGE_H
87