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