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