]>
Commit | Line | Data |
---|---|---|
43ae1d95 | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 The Squid Software Foundation and contributors |
43ae1d95 | 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. | |
43ae1d95 | 7 | */ |
8 | ||
9 | #ifndef SQUID_ESICONTEXT_H | |
10 | #define SQUID_ESICONTEXT_H | |
11 | ||
0655fa4d | 12 | #include "clientStream.h" |
83b053a0 | 13 | #include "error/forward.h" |
602d9612 | 14 | #include "esi/Element.h" |
f66e113e | 15 | #include "esi/Esi.h" |
602d9612 | 16 | #include "esi/Parser.h" |
f522f9b5 | 17 | #include "http/forward.h" |
955394ce | 18 | #include "http/StatusCode.h" |
43ae1d95 | 19 | |
924f73bc | 20 | class ESIVarState; |
43ae1d95 | 21 | class ClientHttpRequest; |
22 | ||
43ae1d95 | 23 | /* ESIContext */ |
24 | ||
25 | class ESIContext : public esiTreeParent, public ESIParserClient | |
26 | { | |
5c2f68b7 | 27 | CBDATA_CLASS(ESIContext); |
43ae1d95 | 28 | |
29 | public: | |
0655fa4d | 30 | typedef RefCount<ESIContext> Pointer; |
a5488e5d | 31 | ESIContext() : |
aee3523a AR |
32 | thisNode(nullptr), |
33 | http(nullptr), | |
f53969cc SM |
34 | errorpage(ERR_NONE), |
35 | errorstatus(Http::scNone), | |
aee3523a AR |
36 | errormessage(nullptr), |
37 | rep(nullptr), | |
f53969cc SM |
38 | outbound_offset(0), |
39 | readpos(0), | |
40 | pos(0), | |
aee3523a | 41 | varState(nullptr), |
f53969cc SM |
42 | cachedASTInUse(false), |
43 | reading_(true), | |
44 | processing(false) { | |
a5488e5d AJ |
45 | memset(&flags, 0, sizeof(flags)); |
46 | } | |
43ae1d95 | 47 | |
337b9aa4 | 48 | ~ESIContext() override; |
43ae1d95 | 49 | |
50 | enum esiKick_t { | |
51 | ESI_KICK_FAILED, | |
52 | ESI_KICK_PENDING, | |
53 | ESI_KICK_SENT, | |
54 | ESI_KICK_INPROGRESS | |
55 | }; | |
56 | ||
57 | /* when esi processing completes */ | |
337b9aa4 AR |
58 | void provideData(ESISegment::Pointer, ESIElement *source) override; |
59 | void fail (ESIElement *source, char const*anError = nullptr) override; | |
43ae1d95 | 60 | void startRead(); |
61 | void finishRead(); | |
62 | bool reading() const; | |
63 | void setError(); | |
924f73bc | 64 | void setErrorMessage(char const *); |
43ae1d95 | 65 | |
66 | void addStackElement (ESIElement::Pointer element); | |
67 | void addLiteral (const char *s, int len); | |
68 | ||
69 | void finishChildren (); | |
70 | ||
71 | clientStreamNode *thisNode; /* our stream node */ | |
72 | /* the request we are processing. HMM: cbdataReferencing this will result | |
73 | * in a circular reference, so we don't. Note: we are automatically freed | |
2f8abb64 | 74 | * when it is, so that's ok. */ |
43ae1d95 | 75 | ClientHttpRequest *http; |
76 | ||
26ac0430 | 77 | struct { |
3d0ac046 HN |
78 | int passthrough:1; |
79 | int oktosend:1; | |
80 | int finished:1; | |
43ae1d95 | 81 | |
61beade2 | 82 | /* an error has occurred, send full body replies |
43ae1d95 | 83 | * regardless. Note that we don't fail midstream |
84 | * because we buffer until we can not fail | |
85 | */ | |
3d0ac046 | 86 | int error:1; |
43ae1d95 | 87 | |
3d0ac046 HN |
88 | int finishedtemplate:1; /* we've read the entire template */ |
89 | int clientwantsdata:1; /* we need to satisfy a read request */ | |
90 | int kicked:1; /* note on reentering the kick routine */ | |
91 | int detached:1; /* our downstream has detached */ | |
92 | } flags; | |
43ae1d95 | 93 | |
43ae1d95 | 94 | err_type errorpage; /* if we error what page to use */ |
955394ce | 95 | Http::StatusCode errorstatus; /* if we error, what code to return */ |
43ae1d95 | 96 | char *errormessage; /* error to pass to error page */ |
f522f9b5 | 97 | HttpReplyPointer rep; /* buffered until we pass data downstream */ |
43ae1d95 | 98 | ESISegment::Pointer buffered; /* unprocessed data - for whatever reason */ |
99 | ESISegment::Pointer incoming; | |
100 | /* processed data we are waiting to send, or for | |
26ac0430 | 101 | * potential errors to be resolved |
43ae1d95 | 102 | */ |
103 | ESISegment::Pointer outbound; | |
104 | ESISegment::Pointer outboundtail; /* our write segment */ | |
105 | /* the offset to the next character to send - | |
26ac0430 AJ |
106 | * non zero if we haven't sent the entire segment |
107 | * for some reason | |
43ae1d95 | 108 | */ |
109 | size_t outbound_offset; | |
e4d72ba2 | 110 | int64_t readpos; /* the logical position we are reading from */ |
111 | int64_t pos; /* the logical position of outbound_offset in the data stream */ | |
43ae1d95 | 112 | |
113 | class ParserState | |
114 | { | |
115 | ||
116 | public: | |
f66e113e | 117 | ESIElement::Pointer stack[ESI_STACK_DEPTH_LIMIT]; /* a stack of esi elements that are open */ |
43ae1d95 | 118 | int stackdepth; /* self explanatory */ |
119 | ESIParser::Pointer theParser; | |
120 | ESIElement::Pointer top(); | |
121 | void init (ESIParserClient *); | |
122 | bool inited() const; | |
123 | ParserState(); | |
124 | void freeResources(); | |
125 | void popAll(); | |
3d0ac046 | 126 | int parsing:1; /* libexpat is not reentrant on the same context */ |
43ae1d95 | 127 | |
128 | private: | |
129 | bool inited_; | |
130 | } | |
9837567d | 131 | parserState; // TODO: refactor this to somewhere else |
43ae1d95 | 132 | |
924f73bc | 133 | ESIVarState *varState; |
43ae1d95 | 134 | ESIElement::Pointer tree; |
135 | ||
136 | esiKick_t kick (); | |
137 | RefCount<ESIContext> cbdataLocker; | |
138 | bool failed() const {return flags.error != 0;} | |
139 | ||
140 | bool cachedASTInUse; | |
141 | ||
142 | private: | |
43ae1d95 | 143 | void fail (); |
144 | void freeResources(); | |
145 | void fixupOutboundTail(); | |
146 | void trimBlanks(); | |
147 | size_t send (); | |
148 | bool reading_; | |
149 | void appendOutboundData(ESISegment::Pointer theData); | |
150 | esiProcessResult_t process (); | |
151 | void parse(); | |
152 | void parseOneBuffer(); | |
153 | void updateCachedAST(); | |
154 | bool hasCachedAST() const; | |
155 | void getCachedAST(); | |
337b9aa4 AR |
156 | void start(const char *el, const char **attr, size_t attrCount) override; |
157 | void end(const char *el) override; | |
158 | void parserDefault (const char *s, int len) override; | |
159 | void parserComment (const char *s) override; | |
43ae1d95 | 160 | bool processing; |
161 | }; | |
162 | ||
163 | #endif /* SQUID_ESICONTEXT_H */ | |
f53969cc | 164 |