2 Copyright (C) 2002-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "WORequest+So.h"
23 #include <NGObjWeb/WEClientCapabilities.h>
26 @implementation WORequest(SoRequestClassification)
28 static BOOL _debugClassify(void) {
29 static int debugOn = -1;
31 debugOn = [[NSUserDefaults standardUserDefaults]
32 boolForKey:@"SoDebugRequestClassification"] ? 1 : 0;
34 NSLog(@"SoDebugRequestClassification: enabled");
36 return debugOn ? YES : NO;
39 - (BOOL)isSoWebDAVRequest {
40 WEClientCapabilities *cc;
43 /* check handler key */
44 if ([[self requestHandlerKey] isEqualToString:@"dav"]) {
45 /* this can be used to force WebDAV */
47 [self logWithFormat:@"classified as WebDAV by request-handler-key"];
51 /* check client type */
52 cc = [self clientCapabilities];
53 if ([cc isDAVClient]) {
54 if (_debugClassify()) {
56 @"classified as WebDAV by user-agent (it's a DAV client)"];
61 /* check translate header */
62 if ((tmp = [self headerForKey:@"translate"])) {
64 if ([h hasPrefix:@"t"] || [h hasPrefix:@"T"]) {
65 if (_debugClassify()) {
67 @"classified as WebDAV by a 'true' translation header"];
73 /* check HTTP methods */
75 static NSMutableSet *davMethods = nil;
76 if (davMethods == nil) {
78 m = [[NSUserDefaults standardUserDefaults]
79 arrayForKey:@"SoWebDAVDetectionMethods"];
80 davMethods = [[NSMutableSet alloc] initWithArray:m];
82 if ([davMethods containsObject:[self method]]) {
83 if (_debugClassify()) {
85 @"classified as WebDAV because of the method name"];
91 /* found no WebDAV indicator */
95 - (BOOL)isSoXmlRpcRequest {
98 if (![[self method] isEqualToString:@"POST"])
99 /* XML-RPC requests must be POST ... */
102 /* check handler key */
103 if ([[self requestHandlerKey] isEqualToString:@"RPC2"]) {
104 /* this can be used to force XML-RPC */
105 if (_debugClassify()) {
107 @"classified as XML-RPC because of request-handler-key"];
112 /* look at content type */
113 t = [self headerForKey:@"content-type"];
114 if (![t hasPrefix:@"text/xml"])
115 /* XML-RPC requests must be text/xml ... */
117 if ([t hasPrefix:@"text/xml+"])
118 /* XML-RPC requests must be text/xml ... */
121 /* look at content length */
122 t = [self headerForKey:@"content-length"];
123 if ([t intValue] < 51)
124 /* an XML-RPC request has some minimum length ... */
127 /* now it becomes difficult, how do we distinguish plain XML and RPC ? */
130 We check for some contents, see below. Not exactly the most
131 efficient thing on earth, but ...
133 must be longer than 50 chars:
134 <methodCall><methodName>x</methodName></methodCall>
139 s = [self contentAsString];
143 crng = [s rangeOfString:@"<methodCall>"];
144 nrng = [s rangeOfString:@"<methodName>"];
145 if (crng.length <= 0) return NO;
146 if (nrng.length <= 0) return NO;
147 if (nrng.location < crng.location) return NO;
149 crng = [s rangeOfString:@"</methodCall>"];
150 nrng = [s rangeOfString:@"</methodName>"];
151 if (crng.length <= 0) return NO;
152 if (nrng.length <= 0) return NO;
153 if (nrng.location > crng.location) return NO;
155 if (_debugClassify()) {
157 @"classified as XML-RPC because of POST and the contents "
158 @"looks like XML-RPC "];
163 /* found no XML-RPC indicator */
167 - (BOOL)isSoSOAPRequest {
168 NSString *soapAction;
170 if ((soapAction = [self headerForKey:@"soapaction"]) == nil)
173 if (_debugClassify()) {
175 @"classified as SOAP because the SOAPAction header is set."];
181 - (BOOL)isSoWCAPRequest {
186 r = [s rangeOfString:@"?"];
187 if (r.length > 0) s = [s substringToIndex:r.location];
188 r = [s rangeOfString:@"#"];
189 if (r.length > 0) s = [s substringToIndex:r.location];
191 return [s hasSuffix:@".wcap"];
194 - (BOOL)isSoBrkDAVRequest {
195 /* a broken WebDAV request */
196 return [[self uri] hasPrefix:@"/servlet/webdav."];
199 @end /* WORequest(SoRequestClassification) */