]> git.ipfire.org Git - thirdparty/squid.git/blob - src/HttpHeader.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / HttpHeader.h
1 /*
2 * Copyright (C) 1996-2017 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_HTTPHEADER_H
10 #define SQUID_HTTPHEADER_H
11
12 #include "base/LookupTable.h"
13 #include "http/RegisteredHeaders.h"
14 /* because we pass a spec by value */
15 #include "HttpHeaderMask.h"
16 #include "mem/forward.h"
17 #include "sbuf/forward.h"
18 #include "SquidString.h"
19
20 #include <vector>
21
22 /* class forward declarations */
23 class HttpHdrCc;
24 class HttpHdrContRange;
25 class HttpHdrRange;
26 class HttpHdrSc;
27 class Packable;
28
29 /** Possible owners of http header */
30 typedef enum {
31 hoNone =0,
32 #if USE_HTCP
33 hoHtcpReply,
34 #endif
35 hoRequest,
36 hoReply,
37 #if USE_OPENSSL
38 hoErrorDetail,
39 #endif
40 hoEnd
41 } http_hdr_owner_type;
42
43 /** Iteration for headers; use HttpHeaderPos as opaque type, do not interpret */
44 typedef ssize_t HttpHeaderPos;
45
46 /* use this and only this to initialize HttpHeaderPos */
47 #define HttpHeaderInitPos (-1)
48
49 class HttpHeaderEntry
50 {
51 MEMPROXY_CLASS(HttpHeaderEntry);
52
53 public:
54 HttpHeaderEntry(Http::HdrType id, const char *name, const char *value);
55 ~HttpHeaderEntry();
56 static HttpHeaderEntry *parse(const char *field_start, const char *field_end);
57 HttpHeaderEntry *clone() const;
58 void packInto(Packable *p) const;
59 int getInt() const;
60 int64_t getInt64() const;
61
62 Http::HdrType id;
63 String name;
64 String value;
65 };
66
67 class ETag;
68 class TimeOrTag;
69
70 class HttpHeader
71 {
72
73 public:
74 HttpHeader();
75 explicit HttpHeader(const http_hdr_owner_type owner);
76 HttpHeader(const HttpHeader &other);
77 ~HttpHeader();
78
79 HttpHeader &operator =(const HttpHeader &other);
80
81 /* Interface functions */
82 void clean();
83 void append(const HttpHeader * src);
84 bool update(HttpHeader const *fresh);
85 void compact();
86 int parse(const char *header_start, size_t len);
87 /// Parses headers stored in a buffer.
88 /// \returns 1 and sets hdr_sz on success
89 /// \returns 0 when needs more data
90 /// \returns -1 on error
91 int parse(const char *buf, size_t buf_len, bool atEnd, size_t &hdr_sz);
92 void packInto(Packable * p, bool mask_sensitive_info=false) const;
93 HttpHeaderEntry *getEntry(HttpHeaderPos * pos) const;
94 HttpHeaderEntry *findEntry(Http::HdrType id) const;
95 int delByName(const char *name);
96 int delById(Http::HdrType id);
97 void delAt(HttpHeaderPos pos, int &headers_deleted);
98 void refreshMask();
99 void addEntry(HttpHeaderEntry * e);
100 void insertEntry(HttpHeaderEntry * e);
101 String getList(Http::HdrType id) const;
102 bool getList(Http::HdrType id, String *s) const;
103 bool conflictingContentLength() const { return conflictingContentLength_; }
104 String getStrOrList(Http::HdrType id) const;
105 String getByName(const SBuf &name) const;
106 String getByName(const char *name) const;
107 String getById(Http::HdrType id) const;
108 /// sets value and returns true iff a [possibly empty] field identified by id is there
109 bool getByIdIfPresent(Http::HdrType id, String &result) const;
110 /// sets value and returns true iff a [possibly empty] named field is there
111 bool getByNameIfPresent(const SBuf &s, String &value) const;
112 bool getByNameIfPresent(const char *name, int namelen, String &value) const;
113 String getByNameListMember(const char *name, const char *member, const char separator) const;
114 String getListMember(Http::HdrType id, const char *member, const char separator) const;
115 int has(Http::HdrType id) const;
116 void putInt(Http::HdrType id, int number);
117 void putInt64(Http::HdrType id, int64_t number);
118 void putTime(Http::HdrType id, time_t htime);
119 void putStr(Http::HdrType id, const char *str);
120 void putAuth(const char *auth_scheme, const char *realm);
121 void putCc(const HttpHdrCc * cc);
122 void putContRange(const HttpHdrContRange * cr);
123 void putRange(const HttpHdrRange * range);
124 void putSc(HttpHdrSc *sc);
125 void putWarning(const int code, const char *const text); ///< add a Warning header
126 void putExt(const char *name, const char *value);
127 int getInt(Http::HdrType id) const;
128 int64_t getInt64(Http::HdrType id) const;
129 time_t getTime(Http::HdrType id) const;
130 const char *getStr(Http::HdrType id) const;
131 const char *getLastStr(Http::HdrType id) const;
132 HttpHdrCc *getCc() const;
133 HttpHdrRange *getRange() const;
134 HttpHdrSc *getSc() const;
135 HttpHdrContRange *getContRange() const;
136 const char *getAuth(Http::HdrType id, const char *auth_scheme) const;
137 ETag getETag(Http::HdrType id) const;
138 TimeOrTag getTimeOrTag(Http::HdrType id) const;
139 int hasListMember(Http::HdrType id, const char *member, const char separator) const;
140 int hasByNameListMember(const char *name, const char *member, const char separator) const;
141 void removeHopByHopEntries();
142 inline bool chunked() const; ///< whether message uses chunked Transfer-Encoding
143
144 /* protected, do not use these, use interface functions instead */
145 std::vector<HttpHeaderEntry *> entries; /**< parsed fields in raw format */
146 HttpHeaderMask mask; /**< bit set <=> entry present */
147 http_hdr_owner_type owner; /**< request or reply */
148 int len; /**< length when packed, not counting terminating null-byte */
149
150 protected:
151 /** \deprecated Public access replaced by removeHopByHopEntries() */
152 void removeConnectionHeaderEntries();
153 /// either finds the end of headers or returns false
154 /// If the end was found:
155 /// *parse_start points to the first character after the header delimiter
156 /// *blk_start points to the first header character (i.e. old parse_start value)
157 /// *blk_end points to the first header delimiter character (CR or LF in CR?LF).
158 /// If block starts where it ends, then there are no fields in the header.
159 static bool Isolate(const char **parse_start, size_t l, const char **blk_start, const char **blk_end);
160 bool needUpdate(const HttpHeader *fresh) const;
161 bool skipUpdateHeader(const Http::HdrType id) const;
162 void updateWarnings();
163
164 private:
165 HttpHeaderEntry *findLastEntry(Http::HdrType id) const;
166 bool conflictingContentLength_; ///< found different Content-Length fields
167 };
168
169 int httpHeaderParseQuotedString(const char *start, const int len, String *val);
170
171 /// quotes string using RFC 7230 quoted-string rules
172 SBuf httpHeaderQuoteString(const char *raw);
173
174 void httpHeaderCalcMask(HttpHeaderMask * mask, Http::HdrType http_hdr_type_enums[], size_t count);
175
176 inline bool
177 HttpHeader::chunked() const
178 {
179 return has(Http::HdrType::TRANSFER_ENCODING) &&
180 hasListMember(Http::HdrType::TRANSFER_ENCODING, "chunked", ',');
181 }
182
183 void httpHeaderInitModule(void);
184
185 #endif /* SQUID_HTTPHEADER_H */
186