]>
Commit | Line | Data |
---|---|---|
985c86bc | 1 | /* |
985c86bc | 2 | * DEBUG: section 73 HTTP Request |
985c86bc | 3 | */ |
4 | ||
582c2af2 | 5 | #include "squid.h" |
985c86bc | 6 | #include "HttpRequestMethod.h" |
7 | #include "wordlist.h" | |
8 | ||
c2a7cefd AJ |
9 | static Http::MethodType & |
10 | operator++ (Http::MethodType &aMethod) | |
985c86bc | 11 | { |
12 | int tmp = (int)aMethod; | |
c2a7cefd | 13 | aMethod = (Http::MethodType)(++tmp); |
985c86bc | 14 | return aMethod; |
15 | } | |
16 | ||
c2a7cefd | 17 | /** |
985c86bc | 18 | * Construct a HttpRequestMethod from a NULL terminated string such as "GET" |
26ac0430 | 19 | * or from a range of chars, * such as "GET" from "GETFOOBARBAZ" |
985c86bc | 20 | * (pass in pointer to G and pointer to F.) |
21 | */ | |
c2a7cefd | 22 | HttpRequestMethod::HttpRequestMethod(char const *begin, char const *end) : theMethod (Http::METHOD_NONE) |
985c86bc | 23 | { |
24 | if (begin == NULL) | |
25 | return; | |
26 | ||
27 | /* | |
28 | * This check for '%' makes sure that we don't | |
29 | * match one of the extension method placeholders, | |
30 | * which have the form %EXT[0-9][0-9] | |
31 | */ | |
32 | ||
33 | if (*begin == '%') | |
34 | return; | |
35 | ||
36 | /* | |
37 | * if e is NULL, b must be NULL terminated and we | |
38 | * make e point to the first whitespace character | |
39 | * after b. | |
40 | */ | |
41 | if (NULL == end) | |
42 | end = begin + strcspn(begin, w_space); | |
26ac0430 | 43 | |
60745f24 | 44 | if (end == begin) { |
c2a7cefd | 45 | theMethod = Http::METHOD_NONE; |
26ac0430 | 46 | return; |
60745f24 | 47 | } |
26ac0430 | 48 | |
c2a7cefd AJ |
49 | for (++theMethod; theMethod < Http::METHOD_ENUM_END; ++theMethod) { |
50 | if (0 == strncasecmp(begin, Http::MethodType_str[theMethod], end-begin)) { | |
985c86bc | 51 | return; |
60745f24 | 52 | } |
985c86bc | 53 | } |
54 | ||
60745f24 | 55 | // if method not found and method string is not null then it is other method |
c2a7cefd | 56 | theMethod = Http::METHOD_OTHER; |
60745f24 | 57 | theImage.limitInit(begin,end-begin); |
985c86bc | 58 | } |
59 | ||
c2a7cefd AJ |
60 | char const* |
61 | HttpRequestMethod::image() const | |
985c86bc | 62 | { |
c2a7cefd AJ |
63 | if (Http::METHOD_OTHER != theMethod) { |
64 | return Http::MethodType_str[theMethod]; | |
65 | } else { | |
66 | if (theImage.size()>0) { | |
67 | return theImage.termedBuf(); | |
68 | } else { | |
69 | return "METHOD_OTHER"; | |
985c86bc | 70 | } |
c2a7cefd AJ |
71 | } |
72 | } | |
985c86bc | 73 | |
c2a7cefd AJ |
74 | bool |
75 | HttpRequestMethod::isHttpSafe() const | |
76 | { | |
77 | // Only a few methods are defined as safe. All others are "unsafe" | |
985c86bc | 78 | |
c2a7cefd AJ |
79 | // NOTE: |
80 | // All known RFCs which register methods are listed in comments. | |
ffb82151 | 81 | // if there is one not listed which defines methods, it needs |
c2a7cefd | 82 | // checking and adding. If only to say it is known to define none. |
985c86bc | 83 | |
ffb82151 | 84 | switch (theMethod) { |
c2a7cefd | 85 | // RFC 2068 - none |
985c86bc | 86 | |
c2a7cefd AJ |
87 | // RFC 2616 section 9.1.1 |
88 | case Http::METHOD_GET: | |
89 | case Http::METHOD_HEAD: | |
90 | case Http::METHOD_OPTIONS: | |
985c86bc | 91 | |
c2a7cefd AJ |
92 | // RFC 3253 section 3.6 |
93 | case Http::METHOD_REPORT: | |
985c86bc | 94 | |
c2a7cefd AJ |
95 | // RFC 3648 - none |
96 | // RFC 3744 - none | |
97 | // RFC 4437 - none | |
98 | // RFC 4791 - none | |
985c86bc | 99 | |
c2a7cefd AJ |
100 | // RFC 4918 section 9.1 |
101 | case Http::METHOD_PROPFIND: | |
985c86bc | 102 | |
c2a7cefd AJ |
103 | // RFC 5323 section 2 |
104 | case Http::METHOD_SEARCH: | |
985c86bc | 105 | |
c2a7cefd AJ |
106 | // RFC 5789 - none |
107 | // RFC 5842 - none | |
985c86bc | 108 | |
c2a7cefd | 109 | return true; |
60745f24 | 110 | |
c2a7cefd AJ |
111 | default: |
112 | return false; | |
914b89a2 | 113 | } |
60745f24 | 114 | } |
115 | ||
26ac0430 | 116 | bool |
c2a7cefd | 117 | HttpRequestMethod::isIdempotent() const |
60745f24 | 118 | { |
c2a7cefd AJ |
119 | // Only a few methods are defined as idempotent. |
120 | ||
121 | // NOTE: | |
122 | // All known RFCs which register methods are listed in comments. | |
ffb82151 | 123 | // if there is one not listed which defines methods, it needs |
c2a7cefd AJ |
124 | // checking and adding. If only to say it is known to define none. |
125 | ||
ffb82151 | 126 | switch (theMethod) { |
c2a7cefd AJ |
127 | // RFC 2068 - TODO check LINK/UNLINK definition |
128 | ||
129 | // RFC 2616 section 9.1.2 | |
130 | case Http::METHOD_GET: | |
131 | case Http::METHOD_HEAD: | |
132 | case Http::METHOD_PUT: | |
133 | case Http::METHOD_DELETE: | |
134 | case Http::METHOD_OPTIONS: | |
135 | case Http::METHOD_TRACE: | |
136 | ||
137 | // RFC 3253 - TODO check | |
138 | // RFC 3648 - TODO check | |
139 | // RFC 3744 - TODO check | |
140 | // RFC 4437 - TODO check | |
141 | // RFC 4791 - TODO check | |
142 | ||
143 | // RFC 4918 section 9 | |
144 | case Http::METHOD_PROPFIND: | |
145 | case Http::METHOD_PROPPATCH: | |
146 | case Http::METHOD_MKCOL: | |
147 | case Http::METHOD_COPY: | |
148 | case Http::METHOD_MOVE: | |
149 | case Http::METHOD_UNLOCK: | |
150 | ||
151 | // RFC 5323 - TODO check | |
152 | // RFC 5789 - TODO check | |
153 | // RFC 5842 - TODO check | |
c1520b67 | 154 | |
c2a7cefd | 155 | return true; |
60745f24 | 156 | |
c2a7cefd | 157 | default: |
60745f24 | 158 | return false; |
c2a7cefd AJ |
159 | } |
160 | } | |
60745f24 | 161 | |
c2a7cefd AJ |
162 | bool |
163 | HttpRequestMethod::respMaybeCacheable() const | |
164 | { | |
165 | // Only a few methods are defined as cacheable. | |
166 | // All other methods from the below RFC are "MUST NOT cache" | |
ffb82151 | 167 | switch (theMethod) { |
c2a7cefd AJ |
168 | // RFC 2616 section 9 |
169 | case Http::METHOD_GET: | |
170 | case Http::METHOD_HEAD: | |
171 | return true; | |
172 | #if WHEN_POST_CACHE_SUPPORTED | |
173 | case Http::METHOD_POST: // Special case. | |
174 | // RFC 2616 specifies POST as possibly cacheable | |
175 | // However, Squid does not implement the required checks yet | |
176 | return true; | |
177 | #endif | |
60745f24 | 178 | |
c2a7cefd AJ |
179 | // RFC 4918 section 9 |
180 | #if WHEN_PROPFIND_CACHE_SUPPORTED | |
181 | case Http::METHOD_PROPFIND: // Special case. | |
182 | // RFC 4918 specifies PROPFIND as possibly cacheable | |
183 | // However, Squid does not implement the required checks yet | |
184 | return true; | |
185 | #endif | |
26ac0430 | 186 | |
c2a7cefd AJ |
187 | // RFC 5323 section 2 - defines no cacheable methods |
188 | ||
189 | // RFC 3253 | |
190 | #if WHEN_CC_NOCACHE_DOES_REVALIDATES_IS_CONFIRMED | |
191 | case Http::METHOD_CHECKOUT: | |
192 | case Http::METHOD_CHECKIN: | |
193 | case Http::METHOD_UNCHECKOUT: | |
194 | case Http::METHOD_MKWORKSPACE: | |
195 | case Http::METHOD_VERSION_CONTROL: | |
196 | case Http::METHOD_UPDATE: | |
197 | case Http::METHOD_LABEL: | |
198 | case Http::METHOD_MERGE: | |
199 | case Http::METHOD_BASELINE_CONTROL: | |
200 | case Http::METHOD_MKACTIVITY: | |
201 | // RFC 3253 defines these methods using "MUST include Cache-Control: no-cache". | |
202 | // | |
203 | // XXX: follow RFC 2616 definition of "no-cache" meaning "MAY cache, always revalidate" | |
204 | // XXX: or treat as unregistered/undefined methods ?? | |
205 | // However, Squid may not implement the required revalidation checks yet | |
206 | return ??; | |
207 | #endif | |
26ac0430 | 208 | |
c2a7cefd AJ |
209 | // Special Squid method tokens are not cacheable. |
210 | // RFC 2616 defines all unregistered or unspecified methods as non-cacheable | |
211 | // until such time as an RFC defines them cacheable. | |
212 | default: | |
213 | return false; | |
214 | } | |
60745f24 | 215 | } |
c1520b67 | 216 | |
26ac0430 | 217 | bool |
c2a7cefd | 218 | HttpRequestMethod::shouldInvalidate() const |
c1520b67 | 219 | { |
c1520b67 | 220 | switch (theMethod) { |
c2a7cefd AJ |
221 | /* RFC 2616 section 13.10 - "MUST invalidate" */ |
222 | case Http::METHOD_POST: | |
223 | case Http::METHOD_PUT: | |
224 | case Http::METHOD_DELETE: | |
26ac0430 | 225 | return true; |
c1520b67 | 226 | |
c2a7cefd AJ |
227 | /* Squid extension to force invalidation */ |
228 | case Http::METHOD_PURGE: | |
26ac0430 | 229 | return true; |
c1520b67 | 230 | |
96385560 BR |
231 | /* |
232 | * RFC 2616 sayeth, in section 13.10, final paragraph: | |
233 | * A cache that passes through requests for methods it does not | |
234 | * understand SHOULD invalidate any entities referred to by the | |
235 | * Request-URI. | |
236 | */ | |
c2a7cefd | 237 | case Http::METHOD_OTHER: |
26ac0430 | 238 | return true; |
c2a7cefd AJ |
239 | |
240 | default: | |
241 | // Methods which are known but not required to invalidate. | |
242 | return false; | |
26ac0430 | 243 | } |
c2a7cefd | 244 | } |
c1520b67 | 245 | |
c2a7cefd AJ |
246 | bool |
247 | HttpRequestMethod::purgesOthers() const | |
248 | { | |
249 | if (shouldInvalidate()) | |
250 | return true; | |
251 | ||
252 | switch (theMethod) { | |
253 | /* common sense suggests purging is not required? */ | |
254 | case Http::METHOD_GET: // XXX: but we do purge HEAD on successful GET | |
255 | case Http::METHOD_HEAD: | |
256 | case Http::METHOD_NONE: | |
257 | case Http::METHOD_CONNECT: | |
258 | case Http::METHOD_TRACE: | |
259 | case Http::METHOD_OPTIONS: | |
260 | case Http::METHOD_PROPFIND: | |
261 | case Http::METHOD_COPY: | |
262 | case Http::METHOD_LOCK: | |
263 | case Http::METHOD_UNLOCK: | |
264 | case Http::METHOD_SEARCH: | |
265 | return false; | |
266 | ||
267 | default: | |
268 | return true; | |
269 | } | |
c1520b67 | 270 | } |