]>
Commit | Line | Data |
---|---|---|
f1974911 | 1 | /* |
262a0e14 | 2 | * $Id$ |
f1974911 | 3 | * |
4 | * | |
5 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
6 | * ---------------------------------------------------------- | |
7 | * | |
8 | * Squid is the result of efforts by numerous individuals from | |
9 | * the Internet community; see the CONTRIBUTORS file for full | |
10 | * details. Many organizations have provided support for Squid's | |
11 | * development; see the SPONSORS file for full details. Squid is | |
12 | * Copyrighted (C) 2001 by the Regents of the University of | |
13 | * California; see the COPYRIGHT file for full details. Squid | |
14 | * incorporates software developed and/or copyrighted by other | |
15 | * sources; see the CREDITS file for full details. | |
16 | * | |
17 | * This program is free software; you can redistribute it and/or modify | |
18 | * it under the terms of the GNU General Public License as published by | |
19 | * the Free Software Foundation; either version 2 of the License, or | |
20 | * (at your option) any later version. | |
26ac0430 | 21 | * |
f1974911 | 22 | * This program is distributed in the hope that it will be useful, |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | * GNU General Public License for more details. | |
26ac0430 | 26 | * |
f1974911 | 27 | * You should have received a copy of the GNU General Public License |
28 | * along with this program; if not, write to the Free Software | |
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
30 | * | |
31 | */ | |
32 | ||
33 | #ifndef SQUID_HTTPMSG_H | |
34 | #define SQUID_HTTPMSG_H | |
35 | ||
36 | #include "typedefs.h" | |
37 | #include "HttpHeader.h" | |
6feb0e7c | 38 | #include "HttpStatusCode.h" |
f1974911 | 39 | #include "HttpVersion.h" |
5f8252d2 | 40 | #include "BodyPipe.h" |
f1974911 | 41 | |
42 | // common parts of HttpRequest and HttpReply | |
43 | ||
44 | class HttpMsg | |
45 | { | |
46 | ||
47 | public: | |
48 | HttpMsg(http_hdr_owner_type owner); | |
4a56ee8d | 49 | virtual ~HttpMsg(); |
f1974911 | 50 | |
51 | virtual void reset() = 0; // will have body when http*Clean()s are gone | |
52 | ||
f1974911 | 53 | void packInto(Packer * p, bool full_uri) const; |
54 | ||
6dd9f4bd | 55 | virtual HttpMsg *_lock(); // please use HTTPMSGLOCK() |
56 | virtual void _unlock(); // please use HTTPMSGUNLOCK() | |
4a56ee8d | 57 | |
26ac0430 AJ |
58 | ///< produce a message copy, except for a few connection-specific settings |
59 | virtual HttpMsg *clone() const = 0; ///< \todo rename: not a true copy? | |
fa0e6114 | 60 | |
3ff65596 AR |
61 | /// [re]sets Content-Length header and cached value |
62 | void setContentLength(int64_t clen); | |
63 | ||
cb1f4d34 | 64 | /** |
4a1acc56 AJ |
65 | * \retval true the message sender asks to keep the connection open. |
66 | * \retval false the message sender will close the connection. | |
67 | * | |
68 | * Factors other than the headers may result in connection closure. | |
69 | */ | |
70 | bool persistent() const; | |
71 | ||
f1974911 | 72 | public: |
73 | HttpVersion http_ver; | |
4a56ee8d | 74 | |
f1974911 | 75 | HttpHeader header; |
76 | ||
77 | HttpHdrCc *cache_control; | |
78 | ||
79 | /* Unsupported, writable, may disappear/change in the future | |
80 | * For replies, sums _stored_ status-line, headers, and <CRLF>. | |
81 | * Also used to report parsed header size if parse() is successful */ | |
82 | int hdr_sz; | |
83 | ||
47f6e231 | 84 | int64_t content_length; |
4a56ee8d | 85 | |
f1974911 | 86 | protocol_t protocol; |
87 | ||
e3ab4be3 | 88 | HttpMsgParseState pstate; /* the current parsing state */ |
4a56ee8d | 89 | |
5f8252d2 | 90 | BodyPipe::Pointer body_pipe; // optional pipeline to receive message body |
91 | ||
e3ab4be3 | 92 | // returns true and sets hdr_sz on success |
93 | // returns false and sets *error to zero when needs more data | |
94 | // returns false and sets *error to a positive http_status code on error | |
f1974911 | 95 | bool parse(MemBuf *buf, bool eol, http_status *error); |
4a56ee8d | 96 | |
59eed7dc | 97 | bool parseCharBuf(const char *buf, ssize_t end); |
4a56ee8d | 98 | |
666f514b | 99 | int httpMsgParseStep(const char *buf, int len, int atEnd); |
4a56ee8d | 100 | |
fb525683 | 101 | virtual int httpMsgParseError(); |
4a56ee8d | 102 | |
60745f24 | 103 | virtual bool expectingBody(const HttpRequestMethod&, int64_t&) const = 0; |
e3ab4be3 | 104 | |
4a56ee8d | 105 | void firstLineBuf(MemBuf&); |
26ac0430 | 106 | |
d67acb4e | 107 | virtual bool inheritProperties(const HttpMsg *aMsg) = 0; |
f1974911 | 108 | |
109 | protected: | |
e1381638 AJ |
110 | /** |
111 | * Validate the message start line is syntactically correct. | |
112 | * Set HTTP error status according to problems found. | |
113 | * | |
114 | * \retval true Status line has no serious problems. | |
115 | * \retval false Status line has a serious problem. Correct response is indicated by error. | |
116 | */ | |
96ee497f | 117 | virtual bool sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, http_status *error) = 0; |
4a56ee8d | 118 | |
f1974911 | 119 | virtual void packFirstLineInto(Packer * p, bool full_uri) const = 0; |
4a56ee8d | 120 | |
429f7150 | 121 | virtual bool parseFirstLine(const char *blk_start, const char *blk_end) = 0; |
4a56ee8d | 122 | |
07947ad8 | 123 | virtual void hdrCacheInit(); |
3cfc19b3 | 124 | |
4a56ee8d | 125 | int lock_count; |
3cfc19b3 | 126 | |
f1974911 | 127 | }; |
128 | ||
a5baffba | 129 | /* Temporary parsing state; might turn into the replacement parser later on */ |
e1381638 AJ |
130 | class HttpParser |
131 | { | |
3ff65596 | 132 | public: |
26ac0430 AJ |
133 | char state; |
134 | const char *buf; | |
135 | int bufsiz; | |
136 | int req_start, req_end; | |
137 | int hdr_start, hdr_end; | |
138 | int m_start, m_end; | |
139 | int u_start, u_end; | |
140 | int v_start, v_end; | |
141 | int v_maj, v_min; | |
719c7e0a AJ |
142 | |
143 | /** HTTP status code to be used on the invalid-request error page | |
144 | * HTTP_STATUS_NONE indicates incomplete parse, HTTP_OK indicates no error. | |
145 | */ | |
146 | http_status request_parse_status; | |
a5baffba | 147 | }; |
a5baffba | 148 | |
149 | extern void HttpParserInit(HttpParser *, const char *buf, int len); | |
52512f28 | 150 | extern int HttpParserParseReqLine(HttpParser *hp); |
151 | ||
4c29340e | 152 | #define MSGDODEBUG 0 |
52512f28 | 153 | #if MSGDODEBUG |
a5baffba | 154 | extern int HttpParserReqSz(HttpParser *); |
155 | extern int HttpParserHdrSz(HttpParser *); | |
156 | extern const char * HttpParserHdrBuf(HttpParser *); | |
157 | extern int HttpParserRequestLen(HttpParser *hp); | |
52512f28 | 158 | #else |
159 | #define HttpParserReqSz(hp) ( (hp)->req_end - (hp)->req_start + 1 ) | |
160 | #define HttpParserHdrSz(hp) ( (hp)->hdr_end - (hp)->hdr_start + 1 ) | |
161 | #define HttpParserHdrBuf(hp) ( (hp)->buf + (hp)->hdr_start ) | |
162 | #define HttpParserRequestLen(hp) ( (hp)->hdr_end - (hp)->req_start + 1 ) | |
163 | #endif | |
f1974911 | 164 | |
666f514b | 165 | SQUIDCEXTERN int httpMsgIsolateHeaders(const char **parse_start, int len, const char **blk_start, const char **blk_end); |
f1974911 | 166 | |
6dd9f4bd | 167 | #define HTTPMSGUNLOCK(a) if(a){(a)->_unlock();(a)=NULL;} |
168 | #define HTTPMSGLOCK(a) (a)->_lock() | |
169 | ||
66c38d9a AR |
170 | // TODO: replace HTTPMSGLOCK with general RefCounting and delete this class |
171 | /// safe HttpMsg pointer wrapper that locks and unlocks the message | |
172 | template <class Msg> | |
173 | class HttpMsgPointerT | |
174 | { | |
175 | public: | |
176 | HttpMsgPointerT(): msg(NULL) {} | |
177 | explicit HttpMsgPointerT(Msg *m): msg(m) { lock(); } | |
178 | virtual ~HttpMsgPointerT() { unlock(); } | |
179 | ||
180 | HttpMsgPointerT(const HttpMsgPointerT &p): msg(p.msg) { lock(); } | |
181 | HttpMsgPointerT &operator =(const HttpMsgPointerT &p) | |
a9d98b6f | 182 | { if (msg != p.msg) { unlock(); msg = p.msg; lock(); } return *this; } |
66c38d9a AR |
183 | |
184 | Msg &operator *() { return *msg; } | |
185 | const Msg &operator *() const { return *msg; } | |
186 | Msg *operator ->() { return msg; } | |
187 | const Msg *operator ->() const { return msg; } | |
188 | operator Msg *() { return msg; } | |
189 | operator const Msg *() const { return msg; } | |
190 | // add more as needed | |
191 | ||
192 | void lock() { if (msg) HTTPMSGLOCK(msg); } ///< prevent msg destruction | |
193 | void unlock() { HTTPMSGUNLOCK(msg); } ///< allows/causes msg destruction | |
194 | ||
195 | private: | |
196 | Msg *msg; | |
197 | }; | |
198 | ||
199 | /// convenience wrapper to create HttpMsgPointerT<> object based on msg type | |
200 | template <class Msg> | |
201 | inline | |
202 | HttpMsgPointerT<Msg> HttpMsgPointer(Msg *msg) | |
203 | { | |
204 | return HttpMsgPointerT<Msg>(msg); | |
205 | } | |
206 | ||
f1974911 | 207 | #endif /* SQUID_HTTPMSG_H */ |