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_HTTPREQUEST_H
10 #define SQUID_HTTPREQUEST_H
11 
12 #include "anyp/Uri.h"
13 #include "base/CbcPointer.h"
14 #include "dns/forward.h"
15 #include "err_type.h"
16 #include "HierarchyLogEntry.h"
17 #include "http/RequestMethod.h"
18 #include "HttpMsg.h"
19 #include "MasterXaction.h"
20 #include "Notes.h"
21 #include "RequestFlags.h"
22 
23 #if USE_AUTH
24 #include "auth/UserRequest.h"
25 #endif
26 #if USE_ADAPTATION
27 #include "adaptation/History.h"
28 #endif
29 #if ICAP_CLIENT
30 #include "adaptation/icap/History.h"
31 #endif
32 #if USE_SQUID_EUI
33 #include "eui/Eui48.h"
34 #include "eui/Eui64.h"
35 #endif
36 
37 class ConnStateData;
38 class Downloader;
39 class AccessLogEntry;
40 typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
41 
42 /*  Http Request */
43 void httpRequestPack(void *obj, Packable *p);
44 
45 class HttpHdrRange;
46 
47 class HttpRequest: public HttpMsg
48 {
49     MEMPROXY_CLASS(HttpRequest);
50 
51 public:
52     typedef RefCount<HttpRequest> Pointer;
53 
54     HttpRequest(const MasterXaction::Pointer &);
55     HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *schemeImage, const char *aUrlpath, const MasterXaction::Pointer &);
56     ~HttpRequest();
57     virtual void reset();
58 
59     void initHTTP(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *schemeImage, const char *aUrlpath);
60 
61     virtual HttpRequest *clone() const;
62 
63     /// Whether response to this request is potentially cachable
64     /// \retval false  Not cacheable.
65     /// \retval true   Possibly cacheable. Response factors will determine.
66     bool maybeCacheable();
67 
68     bool conditional() const; ///< has at least one recognized If-* header
69 
70     /// whether the client is likely to be able to handle a 1xx reply
71     bool canHandle1xx() const;
72 
73     /// \returns a pointer to a local static buffer containing request URI
74     /// that honors strip_query_terms and %-encodes unsafe URI characters
75     char *canonicalCleanUrl() const;
76 
77 #if USE_ADAPTATION
78     /// Returns possibly nil history, creating it if adapt. logging is enabled
79     Adaptation::History::Pointer adaptLogHistory() const;
80     /// Returns possibly nil history, creating it if requested
81     Adaptation::History::Pointer adaptHistory(bool createIfNone = false) const;
82     /// Makes their history ours, throwing on conflicts
83     void adaptHistoryImport(const HttpRequest &them);
84 #endif
85 #if ICAP_CLIENT
86     /// Returns possibly nil history, creating it if icap logging is enabled
87     Adaptation::Icap::History::Pointer icapHistory() const;
88 #endif
89 
90     void recordLookup(const Dns::LookupDetails &detail);
91 
92     /// sets error detail if no earlier detail was available
93     void detailError(err_type aType, int aDetail);
94     /// clear error details, useful for retries/repeats
95     void clearError();
96 
97     /// associates the request with a from-client connection manager
98     void manager(const CbcPointer<ConnStateData> &aMgr, const AccessLogEntryPointer &al);
99 
100 protected:
101     void clean();
102 
103     void init();
104 
105 public:
106     HttpRequestMethod method;
107     AnyP::Uri url; ///< the request URI
108 
109 private:
110 #if USE_ADAPTATION
111     mutable Adaptation::History::Pointer adaptHistory_; ///< per-HTTP transaction info
112 #endif
113 #if ICAP_CLIENT
114     mutable Adaptation::Icap::History::Pointer icapHistory_; ///< per-HTTP transaction info
115 #endif
116 
117 public:
118 #if USE_AUTH
119     Auth::UserRequest::Pointer auth_user_request;
120 #endif
121 
122     /// RFC 7230 section 5.5 - Effective Request URI
123     const SBuf &effectiveRequestUri() const;
124 
125     /**
126      * If defined, store_id_program mapped the request URL to this ID.
127      * Store uses this ID (and not the URL) to find and store entries,
128      * avoiding caching duplicate entries when different URLs point to
129      * "essentially the same" cachable resource.
130      */
131     String store_id;
132 
133     RequestFlags flags;
134 
135     HttpHdrRange *range;
136 
137     time_t ims;
138 
139     int imslen;
140 
141     Ip::Address client_addr;
142 
143 #if FOLLOW_X_FORWARDED_FOR
144     Ip::Address indirect_client_addr;
145 #endif /* FOLLOW_X_FORWARDED_FOR */
146 
147     Ip::Address my_addr;
148 
149     HierarchyLogEntry hier;
150 
151     int dnsWait; ///< sum of DNS lookup delays in milliseconds, for %dt
152 
153     err_type errType;
154     int errDetail; ///< errType-specific detail about the transaction error
155 
156     char *peer_login;       /* Configured peer login:password */
157 
158     char *peer_host;           /* Selected peer host*/
159 
160     time_t lastmod;     /* Used on refreshes */
161 
162     /// The variant second-stage cache key. Generated from Vary header pattern for this request.
163     SBuf vary_headers;
164 
165     char *peer_domain;      /* Configured peer forceddomain */
166 
167     String myportname; // Internal tag name= value from port this requests arrived in.
168 
169     NotePairs::Pointer notes; ///< annotations added by the note directive and helpers
170 
171     String tag;         /* Internal tag for this request */
172 
173     String extacl_user;     /* User name returned by extacl lookup */
174 
175     String extacl_passwd;   /* Password returned by extacl lookup */
176 
177     String extacl_log;      /* String to be used for access.log purposes */
178 
179     String extacl_message;  /* String to be used for error page purposes */
180 
181 #if FOLLOW_X_FORWARDED_FOR
182     String x_forwarded_for_iterator; /* XXX a list of IP addresses */
183 #endif /* FOLLOW_X_FORWARDED_FOR */
184 
185     /// A strong etag of the cached entry. Used for refreshing that entry.
186     String etag;
187 
188     /// whether we have responded with HTTP 100 or FTP 150 already
189     bool forcedBodyContinuation;
190 
191 public:
192     bool multipartRangeRequest() const;
193 
194     bool parseFirstLine(const char *start, const char *end);
195 
196     virtual bool expectingBody(const HttpRequestMethod& unused, int64_t&) const;
197 
198     bool bodyNibbled() const; // the request has a [partially] consumed body
199 
200     int prefixLen() const;
201 
202     void swapOut(StoreEntry * e);
203 
204     void pack(Packable * p) const;
205 
206     static void httpRequestPack(void *obj, Packable *p);
207 
208     static HttpRequest * FromUrl(const SBuf &url, const MasterXaction::Pointer &, const HttpRequestMethod &method = Http::METHOD_GET);
209 
210     /// \deprecated use SBuf variant instead
211     static HttpRequest * FromUrlXXX(const char * url, const MasterXaction::Pointer &, const HttpRequestMethod &method = Http::METHOD_GET);
212 
213     ConnStateData *pinnedConnection();
214 
215     /**
216      * Returns the current StoreID for the request as a nul-terminated char*.
217      * Always returns the current id for the request
218      * (either the effective request URI or modified ID by the helper).
219      */
220     const SBuf storeId();
221 
222     /**
223      * The client connection manager, if known;
224      * Used for any response actions needed directly to the client.
225      * ie 1xx forwarding or connection pinning state changes
226      */
227     CbcPointer<ConnStateData> clientConnectionManager;
228 
229     /// The Downloader object which initiated the HTTP request if any
230     CbcPointer<Downloader> downloader;
231 
232     /// the master transaction this request belongs to. Never nil.
233     MasterXaction::Pointer masterXaction;
234 
235     /// forgets about the cached Range header (for a reason)
236     void ignoreRange(const char *reason);
237     int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */
238 
239 private:
240     mutable int64_t rangeOffsetLimit;  /* caches the result of getRangeOffsetLimit */
241 
242 protected:
243     virtual void packFirstLineInto(Packable * p, bool full_uri) const;
244 
245     virtual bool sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error);
246 
247     virtual void hdrCacheInit();
248 
249     virtual bool inheritProperties(const HttpMsg *aMsg);
250 };
251 
252 #endif /* SQUID_HTTPREQUEST_H */
253 
254