]> err.no Git - sope/blob - sope-appserver/NGObjWeb/SoObjects/WORequest+So.m
added some WebDrive WebDAV properties
[sope] / sope-appserver / NGObjWeb / SoObjects / WORequest+So.m
1 /*
2   Copyright (C) 2002-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #include "WORequest+So.h"
23 #include <NGObjWeb/WEClientCapabilities.h>
24 #include "common.h"
25
26 @implementation WORequest(SoRequestClassification)
27
28 static BOOL _debugClassify(void) {
29   static int debugOn = -1;
30   if (debugOn == -1) {
31     debugOn = [[NSUserDefaults standardUserDefaults] 
32                 boolForKey:@"SoDebugRequestClassification"] ? 1 : 0;
33     if (debugOn)
34       NSLog(@"SoDebugRequestClassification: enabled");
35   }
36   return debugOn ? YES : NO;
37 }
38
39 - (BOOL)isSoWebDAVRequest {
40   WEClientCapabilities *cc;
41   id tmp;
42   
43   /* check handler key */
44   if ([[self requestHandlerKey] isEqualToString:@"dav"]) {
45     /* this can be used to force WebDAV */
46     if (_debugClassify())
47       [self logWithFormat:@"classified as WebDAV by request-handler-key"];
48     return YES;
49   }
50   
51   /* check client type */
52   cc = [self clientCapabilities];
53   if ([cc isDAVClient]) {
54     if (_debugClassify()) {
55       [self logWithFormat: 
56               @"classified as WebDAV by user-agent (it's a DAV client)"];
57     }
58     return YES;
59   }
60   
61   /* check translate header */
62   if ((tmp = [self headerForKey:@"translate"])) {
63     NSString *h = tmp;
64     if ([h hasPrefix:@"t"] || [h hasPrefix:@"T"]) {
65       if (_debugClassify()) {
66         [self logWithFormat:
67                 @"classified as WebDAV by a 'true' translation header"];
68       }
69       return YES;
70     }
71   }
72   
73   /* check HTTP methods */
74   {
75     static NSMutableSet *davMethods = nil;
76     if (davMethods == nil) {
77       NSArray *m;
78       m = [[NSUserDefaults standardUserDefaults] 
79                            arrayForKey:@"SoWebDAVDetectionMethods"];
80       davMethods = [[NSMutableSet alloc] initWithArray:m];
81     }
82     if ([davMethods containsObject:[self method]]) {
83       if (_debugClassify()) {
84         [self logWithFormat:
85                 @"classified as WebDAV because of the method name"];
86       }
87       return YES;
88     }
89   }
90   
91   /* found no WebDAV indicator */
92   return NO;
93 }
94
95 - (BOOL)isSoXmlRpcRequest {
96   NSString *t;
97   
98   if (![[self method] isEqualToString:@"POST"])
99     /* XML-RPC requests must be POST ... */
100     return NO;
101   
102   /* check handler key */
103   if ([[self requestHandlerKey] isEqualToString:@"RPC2"]) {
104     /* this can be used to force XML-RPC */
105     if (_debugClassify()) {
106       [self logWithFormat:
107               @"classified as XML-RPC because of request-handler-key"];
108     }
109     return YES;
110   }
111   
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 ... */
116     return NO;
117   if ([t hasPrefix:@"text/xml+"])
118     /* XML-RPC requests must be text/xml ... */
119     return NO;
120
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 ... */
125     return NO;
126   
127   /* now it becomes difficult, how do we distinguish plain XML and RPC ? */
128   {
129     /*
130       We check for some contents, see below. Not exactly the most
131       efficient thing on earth, but ...
132       
133       must be longer than 50 chars:
134       <methodCall><methodName>x</methodName></methodCall>
135     */
136     NSString *s;
137     NSRange crng, nrng;
138
139     s = [self contentAsString];
140     if ([s length] < 51)
141       return NO;
142
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;
148
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;
154
155     if (_debugClassify()) {
156       [self logWithFormat:
157               @"classified as XML-RPC because of POST and the contents "
158               @"looks like XML-RPC "];
159     }
160     return YES;
161   }
162   
163   /* found no XML-RPC indicator */
164   return NO;
165 }
166
167 - (BOOL)isSoSOAPRequest {
168   NSString *soapAction;
169   
170   if ((soapAction = [self headerForKey:@"soapaction"]) == nil)
171     return NO;
172   
173   if (_debugClassify()) {
174     [self logWithFormat:
175             @"classified as SOAP because the SOAPAction header is set."];
176   }
177   
178   return YES;
179 }
180
181 - (BOOL)isSoWCAPRequest {
182   NSString *s;
183   NSRange  r;
184   
185   s = [self uri];
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];
190   
191   return [s hasSuffix:@".wcap"];
192 }
193
194 - (BOOL)isSoBrkDAVRequest {
195   /* a broken WebDAV request */
196   return [[self uri] hasPrefix:@"/servlet/webdav."];
197 }
198
199 @end /* WORequest(SoRequestClassification) */