]> git.ipfire.org Git - thirdparty/squid.git/blame - src/HttpHeader.h
Log PROXY protocol v2 TLVs; fix PROXY protocol parsing bugs (#342)
[thirdparty/squid.git] / src / HttpHeader.h
CommitLineData
e6ccf245 1/*
f6e9a3ee 2 * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
e6ccf245 3 *
bbc27441
AJ
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.
e6ccf245 7 */
8
9#ifndef SQUID_HTTPHEADER_H
10#define SQUID_HTTPHEADER_H
11
90be6ff5 12#include "anyp/ProtocolVersion.h"
383154d7 13#include "base/LookupTable.h"
1139d406 14#include "http/RegisteredHeaders.h"
528b2c61 15/* because we pass a spec by value */
25b6a907 16#include "HttpHeaderMask.h"
c3b51d64 17#include "mem/PoolingAllocator.h"
92e8f3ad 18#include "sbuf/forward.h"
71b673d4 19#include "SquidString.h"
43ca19e0 20
b7347197
FC
21#include <vector>
22
696a257c 23/* class forward declarations */
696a257c 24class HttpHdrCc;
71b673d4 25class HttpHdrContRange;
696a257c 26class HttpHdrRange;
71b673d4 27class HttpHdrSc;
17802cf1 28class Packable;
696a257c 29
63be0a78 30/** Possible owners of http header */
25b6a907 31typedef enum {
0b57cb3d 32 hoNone =0,
25b6a907 33#if USE_HTCP
34 hoHtcpReply,
35#endif
36 hoRequest,
02259ff8 37 hoReply,
cb4f4424 38#if USE_OPENSSL
02259ff8
CT
39 hoErrorDetail,
40#endif
41 hoEnd
25b6a907 42} http_hdr_owner_type;
43
63be0a78 44/** Iteration for headers; use HttpHeaderPos as opaque type, do not interpret */
985c86bc 45typedef ssize_t HttpHeaderPos;
46
47/* use this and only this to initialize HttpHeaderPos */
48#define HttpHeaderInitPos (-1)
49
eede25e7 50class HttpHeaderEntry
51{
741c2986 52 MEMPROXY_CLASS(HttpHeaderEntry);
eede25e7 53
54public:
d5f18517 55 HttpHeaderEntry(Http::HdrType id, const SBuf &name, const char *value);
eede25e7 56 ~HttpHeaderEntry();
cdce6c61 57 static HttpHeaderEntry *parse(const char *field_start, const char *field_end);
eede25e7 58 HttpHeaderEntry *clone() const;
17802cf1 59 void packInto(Packable *p) const;
eede25e7 60 int getInt() const;
47f6e231 61 int64_t getInt64() const;
741c2986 62
789217a2 63 Http::HdrType id;
d5f18517 64 SBuf name;
30abd221 65 String value;
eede25e7 66};
67
81a94152
AJ
68class ETag;
69class TimeOrTag;
70
924f73bc 71class HttpHeader
72{
73
74public:
75faaa7a 75 HttpHeader();
5e5fa5b1
AR
76 explicit HttpHeader(const http_hdr_owner_type owner);
77 HttpHeader(const HttpHeader &other);
75faaa7a 78 ~HttpHeader();
5e5fa5b1
AR
79
80 HttpHeader &operator =(const HttpHeader &other);
81
924f73bc 82 /* Interface functions */
519e0948 83 void clean();
a9925b40 84 void append(const HttpHeader * src);
1a210de4 85 bool update(HttpHeader const *fresh);
394499bd 86 void compact();
4f1c93a7 87 int parse(const char *header_start, size_t len, Http::ContentLengthInterpreter &interpreter);
69c698a3
EB
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
4f1c93a7 92 int parse(const char *buf, size_t buf_len, bool atEnd, size_t &hdr_sz, Http::ContentLengthInterpreter &interpreter);
17802cf1 93 void packInto(Packable * p, bool mask_sensitive_info=false) const;
a9925b40 94 HttpHeaderEntry *getEntry(HttpHeaderPos * pos) const;
789217a2 95 HttpHeaderEntry *findEntry(Http::HdrType id) const;
d5f18517
AJ
96 /// deletes all fields with a given name, if any.
97 /// \return #fields deleted
98 int delByName(const SBuf &name);
99 /// \deprecated use SBuf method instead. performance regression: reallocates
100 int delByName(const char *name) { return delByName(SBuf(name)); }
789217a2 101 int delById(Http::HdrType id);
ba9fb01d 102 void delAt(HttpHeaderPos pos, int &headers_deleted);
103 void refreshMask();
a9925b40 104 void addEntry(HttpHeaderEntry * e);
105 void insertEntry(HttpHeaderEntry * e);
789217a2
FC
106 String getList(Http::HdrType id) const;
107 bool getList(Http::HdrType id, String *s) const;
3e42b356 108 bool conflictingContentLength() const { return conflictingContentLength_; }
789217a2 109 String getStrOrList(Http::HdrType id) const;
81ab22b6 110 String getByName(const SBuf &name) const;
30abd221 111 String getByName(const char *name) const;
81ab22b6 112 String getById(Http::HdrType id) const;
f29d429e
EB
113 /// returns true iff a [possibly empty] field identified by id is there
114 /// when returning true, also sets the `result` parameter (if it is not nil)
115 bool getByIdIfPresent(Http::HdrType id, String *result) const;
116 /// returns true iff a [possibly empty] named field is there
117 /// when returning true, also sets the `value` parameter (if it is not nil)
118 bool hasNamed(const SBuf &s, String *value = 0) const;
d5f18517
AJ
119 /// \deprecated use SBuf method instead.
120 bool hasNamed(const char *name, unsigned int namelen, String *value = 0) const;
36c774f7
EB
121 /// searches for the first matching key=value pair within the name-identified field
122 /// \returns the value of the found pair or an empty string
123 SBuf getByNameListMember(const char *name, const char *member, const char separator) const;
124 /// searches for the first matching key=value pair within the field
125 /// \returns the value of the found pair or an empty string
126 SBuf getListMember(Http::HdrType id, const char *member, const char separator) const;
789217a2 127 int has(Http::HdrType id) const;
90be6ff5
EB
128 /// Appends "this cache" information to VIA header field.
129 /// Takes the initial VIA value from "from" parameter, if provided.
130 void addVia(const AnyP::ProtocolVersion &ver, const HttpHeader *from = 0);
789217a2
FC
131 void putInt(Http::HdrType id, int number);
132 void putInt64(Http::HdrType id, int64_t number);
133 void putTime(Http::HdrType id, time_t htime);
789217a2 134 void putStr(Http::HdrType id, const char *str);
a9925b40 135 void putAuth(const char *auth_scheme, const char *realm);
136 void putCc(const HttpHdrCc * cc);
137 void putContRange(const HttpHdrContRange * cr);
138 void putRange(const HttpHdrRange * range);
139 void putSc(HttpHdrSc *sc);
bcfba8bd 140 void putWarning(const int code, const char *const text); ///< add a Warning header
a9925b40 141 void putExt(const char *name, const char *value);
789217a2
FC
142 int getInt(Http::HdrType id) const;
143 int64_t getInt64(Http::HdrType id) const;
144 time_t getTime(Http::HdrType id) const;
145 const char *getStr(Http::HdrType id) const;
146 const char *getLastStr(Http::HdrType id) const;
a9925b40 147 HttpHdrCc *getCc() const;
148 HttpHdrRange *getRange() const;
149 HttpHdrSc *getSc() const;
150 HttpHdrContRange *getContRange() const;
789217a2
FC
151 const char *getAuth(Http::HdrType id, const char *auth_scheme) const;
152 ETag getETag(Http::HdrType id) const;
153 TimeOrTag getTimeOrTag(Http::HdrType id) const;
154 int hasListMember(Http::HdrType id, const char *member, const char separator) const;
a9925b40 155 int hasByNameListMember(const char *name, const char *member, const char separator) const;
2cdeea82 156 void removeHopByHopEntries();
c3d0ba0c 157 inline bool chunked() const; ///< whether message uses chunked Transfer-Encoding
63be0a78 158
924f73bc 159 /* protected, do not use these, use interface functions instead */
c3b51d64 160 std::vector<HttpHeaderEntry*, PoolingAllocator<HttpHeaderEntry*> > entries; /**< parsed fields in raw format */
f53969cc
SM
161 HttpHeaderMask mask; /**< bit set <=> entry present */
162 http_hdr_owner_type owner; /**< request or reply */
163 int len; /**< length when packed, not counting terminating null-byte */
a9925b40 164
2cdeea82 165protected:
63be0a78 166 /** \deprecated Public access replaced by removeHopByHopEntries() */
2cdeea82 167 void removeConnectionHeaderEntries();
69c698a3
EB
168 /// either finds the end of headers or returns false
169 /// If the end was found:
170 /// *parse_start points to the first character after the header delimiter
171 /// *blk_start points to the first header character (i.e. old parse_start value)
172 /// *blk_end points to the first header delimiter character (CR or LF in CR?LF).
173 /// If block starts where it ends, then there are no fields in the header.
174 static bool Isolate(const char **parse_start, size_t l, const char **blk_start, const char **blk_end);
1a210de4 175 bool needUpdate(const HttpHeader *fresh) const;
2d4f252d
EB
176 bool skipUpdateHeader(const Http::HdrType id) const;
177 void updateWarnings();
63be0a78 178
a9925b40 179private:
789217a2 180 HttpHeaderEntry *findLastEntry(Http::HdrType id) const;
3e42b356 181 bool conflictingContentLength_; ///< found different Content-Length fields
924f73bc 182};
528b2c61 183
8a648e8d 184int httpHeaderParseQuotedString(const char *start, const int len, String *val);
a2c7f09a 185
e7ce227f
AR
186/// quotes string using RFC 7230 quoted-string rules
187SBuf httpHeaderQuoteString(const char *raw);
a2c7f09a 188
789217a2 189void httpHeaderCalcMask(HttpHeaderMask * mask, Http::HdrType http_hdr_type_enums[], size_t count);
25b6a907 190
c3d0ba0c
AR
191inline bool
192HttpHeader::chunked() const
193{
789217a2
FC
194 return has(Http::HdrType::TRANSFER_ENCODING) &&
195 hasListMember(Http::HdrType::TRANSFER_ENCODING, "chunked", ',');
c3d0ba0c
AR
196}
197
8a648e8d 198void httpHeaderInitModule(void);
ec6f82c1 199
e6ccf245 200#endif /* SQUID_HTTPHEADER_H */
f53969cc 201