]> git.ipfire.org Git - thirdparty/squid.git/blob - src/http.h
e5f8fdb3842d656bb8ed0d3484ab2aa1dcd5aaec
[thirdparty/squid.git] / src / http.h
1 /*
2 * Copyright (C) 1996-2025 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_SRC_HTTP_H
10 #define SQUID_SRC_HTTP_H
11
12 #include "clients/Client.h"
13 #include "comm.h"
14 #include "http/forward.h"
15 #include "http/StateFlags.h"
16 #include "sbuf/SBuf.h"
17
18 #include <optional>
19
20 class FwdState;
21 class HttpHeader;
22 class String;
23
24 class HttpStateData : public Client
25 {
26 CBDATA_CHILD(HttpStateData);
27
28 public:
29
30 /// assists in making and relaying entry caching/sharing decision
31 class ReuseDecision
32 {
33 public:
34 enum Answers { reuseNot = 0, cachePositively, cacheNegatively, doNotCacheButShare };
35
36 ReuseDecision(const StoreEntry *e, const Http::StatusCode code);
37 /// stores the corresponding decision
38 Answers make(const Answers ans, const char *why);
39
40 Answers answer; ///< the decision id
41 const char *reason; ///< the decision reason
42 const StoreEntry *entry; ///< entry for debugging
43 const Http::StatusCode statusCode; ///< HTTP status for debugging
44 };
45
46 HttpStateData(FwdState *);
47 ~HttpStateData() override;
48
49 static void httpBuildRequestHeader(HttpRequest * request,
50 StoreEntry * entry,
51 const AccessLogEntryPointer &al,
52 HttpHeader * hdr_out,
53 const CachePeer *peer,
54 const Http::StateFlags &flags);
55
56 const Comm::ConnectionPointer & dataConnection() const override;
57 /* should be private */
58 bool sendRequest();
59 void processReplyHeader();
60 void processReplyBody() override;
61 void readReply(const CommIoCbParams &io);
62 void maybeReadVirginBody() override; // read response data from the network
63
64 // Checks whether the response is cacheable/shareable.
65 ReuseDecision::Answers reusableReply(ReuseDecision &decision);
66
67 CachePeer *_peer = nullptr; /* CachePeer request made to */
68 int eof = 0; /* reached end-of-object? */
69 int lastChunk = 0; /* reached last chunk of a chunk-encoded reply */
70 Http::StateFlags flags;
71 SBuf inBuf; ///< I/O buffer for receiving server responses
72 bool ignoreCacheControl = false;
73 bool surrogateNoStore = false;
74
75 /// Upgrade header value sent to the origin server or cache peer.
76 String *upgradeHeaderOut = nullptr;
77
78 void processSurrogateControl(HttpReply *);
79
80 protected:
81 /* Client API */
82 void noteDelayAwareReadChance() override;
83
84 void processReply();
85 void proceedAfter1xx();
86 void handle1xx(const HttpReplyPointer &);
87 void drop1xx(const char *reason);
88
89 private:
90 /**
91 * The current server connection.
92 * Maybe open, closed, or NULL.
93 * Use doneWithServer() to check if the server is available for use.
94 */
95 Comm::ConnectionPointer serverConnection;
96 AsyncCall::Pointer closeHandler;
97 enum ConnectionStatus {
98 INCOMPLETE_MSG,
99 COMPLETE_PERSISTENT_MSG,
100 COMPLETE_NONPERSISTENT_MSG
101 };
102 ConnectionStatus statusIfComplete() const;
103 ConnectionStatus persistentConnStatus() const;
104 void keepaliveAccounting(HttpReply *);
105 void checkDateSkew(HttpReply *);
106
107 bool continueAfterParsingHeader();
108 void truncateVirginBody();
109
110 void start() override;
111 void haveParsedReplyHeaders() override;
112 bool getMoreRequestBody(MemBuf &buf) override;
113 void closeServer() override; // end communication with the server
114 bool doneWithServer() const override; // did we end communication?
115 void abortAll(const char *reason) override; // abnormal termination
116 bool mayReadVirginReplyBody() const override;
117
118 void abortTransaction(const char *reason) { abortAll(reason); } // abnormal termination
119
120 size_t calcReadBufferCapacityLimit() const;
121 std::optional<size_t> canBufferMoreReplyBytes() const;
122 size_t maybeMakeSpaceAvailable(size_t maxReadSize);
123
124 // consuming request body
125 virtual void handleMoreRequestBodyAvailable();
126 void handleRequestBodyProducerAborted() override;
127
128 void writeReplyBody();
129 bool decodeAndWriteReplyBody();
130 bool finishingBrokenPost();
131 bool finishingChunkedRequest();
132 void doneSendingRequestBody() override;
133 void requestBodyHandler(MemBuf &);
134 void sentRequestBody(const CommIoCbParams &io) override;
135 void wroteLast(const CommIoCbParams &io);
136 void sendComplete();
137 void httpStateConnClosed(const CommCloseCbParams &params);
138 void httpTimeout(const CommTimeoutCbParams &params);
139 void markPrematureReplyBodyEofFailure();
140
141 mb_size_t buildRequestPrefix(MemBuf * mb);
142 void forwardUpgrade(HttpHeader&);
143 static bool decideIfWeDoRanges (HttpRequest * orig_request);
144 bool peerSupportsConnectionPinning() const;
145 const char *blockSwitchingProtocols(const HttpReply&) const;
146
147 /// Parser being used at present to parse the HTTP/ICY server response.
148 Http1::ResponseParserPointer hp;
149 Http1::TeChunkedParser *httpChunkDecoder = nullptr;
150
151 /// amount of message payload/body received so far.
152 int64_t payloadSeen = 0;
153 /// positive when we read more than we wanted
154 int64_t payloadTruncated = 0;
155
156 /// whether we are waiting for our Comm::Read() handler to be called
157 bool waitingForCommRead = false;
158
159 /// Whether we received a Date header older than that of a matching
160 /// cached response.
161 bool sawDateGoBack = false;
162 };
163
164 std::ostream &operator <<(std::ostream &os, const HttpStateData::ReuseDecision &d);
165
166 int httpCachable(const HttpRequestMethod&);
167 void httpStart(FwdState *);
168 SBuf httpMakeVaryMark(HttpRequest * request, HttpReply const * reply);
169
170 #endif /* SQUID_SRC_HTTP_H */
171