]>
Commit | Line | Data |
---|---|---|
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 ¶ms); | |
138 | void httpTimeout(const CommTimeoutCbParams ¶ms); | |
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 |