]>
Commit | Line | Data |
---|---|---|
e6ccf245 | 1 | /* |
1f7b830e | 2 | * Copyright (C) 1996-2025 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 | ||
ff9d9458 FC |
9 | #ifndef SQUID_SRC_HTTP_H |
10 | #define SQUID_SRC_HTTP_H | |
e6ccf245 | 11 | |
fccd4a86 | 12 | #include "clients/Client.h" |
c4b7a5a9 | 13 | #include "comm.h" |
51c3e7f0 | 14 | #include "http/forward.h" |
bad9c5e4 | 15 | #include "http/StateFlags.h" |
90ab8f20 | 16 | #include "sbuf/SBuf.h" |
314782d4 | 17 | |
50c5af88 AR |
18 | #include <optional> |
19 | ||
314782d4 | 20 | class FwdState; |
c6983ec7 | 21 | class HttpHeader; |
1c2b4465 | 22 | class String; |
e6ccf245 | 23 | |
fccd4a86 | 24 | class HttpStateData : public Client |
62e76326 | 25 | { |
337b9aa4 | 26 | CBDATA_CHILD(HttpStateData); |
62e76326 | 27 | |
28 | public: | |
39fe14b2 EB |
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 | ||
11913361 | 46 | HttpStateData(FwdState *); |
337b9aa4 | 47 | ~HttpStateData() override; |
2afaba07 | 48 | |
99d4c5e0 | 49 | static void httpBuildRequestHeader(HttpRequest * request, |
99d4c5e0 | 50 | StoreEntry * entry, |
4bf68cfa | 51 | const AccessLogEntryPointer &al, |
99d4c5e0 | 52 | HttpHeader * hdr_out, |
16b17ba9 | 53 | const CachePeer *peer, |
bad9c5e4 | 54 | const Http::StateFlags &flags); |
5f8252d2 | 55 | |
337b9aa4 | 56 | const Comm::ConnectionPointer & dataConnection() const override; |
4eb368f9 | 57 | /* should be private */ |
5f8252d2 | 58 | bool sendRequest(); |
2afaba07 | 59 | void processReplyHeader(); |
337b9aa4 | 60 | void processReplyBody() override; |
dc56a9b1 | 61 | void readReply(const CommIoCbParams &io); |
337b9aa4 | 62 | void maybeReadVirginBody() override; // read response data from the network |
2b59002c | 63 | |
39fe14b2 EB |
64 | // Checks whether the response is cacheable/shareable. |
65 | ReuseDecision::Answers reusableReply(ReuseDecision &decision); | |
2afaba07 | 66 | |
c31f43b9 FC |
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 */ | |
bad9c5e4 | 70 | Http::StateFlags flags; |
395a814a | 71 | SBuf inBuf; ///< I/O buffer for receiving server responses |
c31f43b9 FC |
72 | bool ignoreCacheControl = false; |
73 | bool surrogateNoStore = false; | |
5f8252d2 | 74 | |
1c2b4465 CT |
75 | /// Upgrade header value sent to the origin server or cache peer. |
76 | String *upgradeHeaderOut = nullptr; | |
77 | ||
43ae1d95 | 78 | void processSurrogateControl(HttpReply *); |
2afaba07 | 79 | |
7c4e4e7f | 80 | protected: |
a928fdfd | 81 | /* Client API */ |
337b9aa4 | 82 | void noteDelayAwareReadChance() override; |
a928fdfd | 83 | |
655daa06 AR |
84 | void processReply(); |
85 | void proceedAfter1xx(); | |
80a6a08a | 86 | void handle1xx(const HttpReplyPointer &); |
1c2b4465 | 87 | void drop1xx(const char *reason); |
655daa06 | 88 | |
528b2c61 | 89 | private: |
8d71285d AJ |
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; | |
dc56a9b1 | 96 | AsyncCall::Pointer closeHandler; |
528b2c61 | 97 | enum ConnectionStatus { |
62e76326 | 98 | INCOMPLETE_MSG, |
99 | COMPLETE_PERSISTENT_MSG, | |
100 | COMPLETE_NONPERSISTENT_MSG | |
528b2c61 | 101 | }; |
102 | ConnectionStatus statusIfComplete() const; | |
103 | ConnectionStatus persistentConnStatus() const; | |
2afaba07 | 104 | void keepaliveAccounting(HttpReply *); |
105 | void checkDateSkew(HttpReply *); | |
5f8252d2 | 106 | |
ba82c452 | 107 | bool continueAfterParsingHeader(); |
821beb5e | 108 | void truncateVirginBody(); |
ba82c452 | 109 | |
337b9aa4 AR |
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; | |
5f8252d2 | 117 | |
92cfc72f CT |
118 | void abortTransaction(const char *reason) { abortAll(reason); } // abnormal termination |
119 | ||
50c5af88 AR |
120 | size_t calcReadBufferCapacityLimit() const; |
121 | std::optional<size_t> canBufferMoreReplyBytes() const; | |
122 | size_t maybeMakeSpaceAvailable(size_t maxReadSize); | |
1ad68518 | 123 | |
5f8252d2 | 124 | // consuming request body |
125 | virtual void handleMoreRequestBodyAvailable(); | |
337b9aa4 | 126 | void handleRequestBodyProducerAborted() override; |
5f8252d2 | 127 | |
128 | void writeReplyBody(); | |
af0bb8e5 | 129 | bool decodeAndWriteReplyBody(); |
39cb8c41 AR |
130 | bool finishingBrokenPost(); |
131 | bool finishingChunkedRequest(); | |
337b9aa4 | 132 | void doneSendingRequestBody() override; |
3b299123 | 133 | void requestBodyHandler(MemBuf &); |
337b9aa4 | 134 | void sentRequestBody(const CommIoCbParams &io) override; |
39cb8c41 AR |
135 | void wroteLast(const CommIoCbParams &io); |
136 | void sendComplete(); | |
dc56a9b1 | 137 | void httpStateConnClosed(const CommCloseCbParams ¶ms); |
138 | void httpTimeout(const CommTimeoutCbParams ¶ms); | |
21f90159 | 139 | void markPrematureReplyBodyEofFailure(); |
dc56a9b1 | 140 | |
e24f13cd | 141 | mb_size_t buildRequestPrefix(MemBuf * mb); |
1c2b4465 | 142 | void forwardUpgrade(HttpHeader&); |
99d4c5e0 | 143 | static bool decideIfWeDoRanges (HttpRequest * orig_request); |
d67acb4e | 144 | bool peerSupportsConnectionPinning() const; |
1c2b4465 | 145 | const char *blockSwitchingProtocols(const HttpReply&) const; |
2afaba07 | 146 | |
f542211b AJ |
147 | /// Parser being used at present to parse the HTTP/ICY server response. |
148 | Http1::ResponseParserPointer hp; | |
c31f43b9 | 149 | Http1::TeChunkedParser *httpChunkDecoder = nullptr; |
8e100780 AJ |
150 | |
151 | /// amount of message payload/body received so far. | |
c31f43b9 | 152 | int64_t payloadSeen = 0; |
8e100780 | 153 | /// positive when we read more than we wanted |
c31f43b9 | 154 | int64_t payloadTruncated = 0; |
eace013e | 155 | |
cc8b26f9 AR |
156 | /// whether we are waiting for our Comm::Read() handler to be called |
157 | bool waitingForCommRead = false; | |
158 | ||
eace013e EB |
159 | /// Whether we received a Date header older than that of a matching |
160 | /// cached response. | |
c31f43b9 | 161 | bool sawDateGoBack = false; |
e6ccf245 | 162 | }; |
163 | ||
39fe14b2 EB |
164 | std::ostream &operator <<(std::ostream &os, const HttpStateData::ReuseDecision &d); |
165 | ||
8a648e8d FC |
166 | int httpCachable(const HttpRequestMethod&); |
167 | void httpStart(FwdState *); | |
90ab8f20 | 168 | SBuf httpMakeVaryMark(HttpRequest * request, HttpReply const * reply); |
fc54b8d2 | 169 | |
ff9d9458 | 170 | #endif /* SQUID_SRC_HTTP_H */ |
f53969cc | 171 |