]> err.no Git - sope/blob - sope-appserver/NGObjWeb/WOHTTPURLHandle.m
Improved WORepetition's implementation to be more convenient in regards to the 'list...
[sope] / sope-appserver / NGObjWeb / WOHTTPURLHandle.m
1 /*
2   Copyright (C) 2000-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 #import <Foundation/NSObject.h> // required by gstep-base
23 #import <Foundation/NSURLHandle.h>
24 #import <Foundation/NSURL.h>
25
26 @class WOResponse;
27
28 /*
29   An URLHandle class which uses WO classes (WOHTTPConnection, WORequest, ..)
30   to get/set HTTP resources.
31 */
32
33 @interface WOHTTPURLHandle : NSURLHandle
34 {
35   NSURL             *url;
36   BOOL              shallCache;
37   WOResponse        *cachedResponse;
38   NSURLHandleStatus status;
39 }
40 @end
41
42 #include <NGObjWeb/WOHTTPConnection.h>
43 #include <NGObjWeb/WOResponse.h>
44 #include <NGObjWeb/WORequest.h>
45 #include "common.h"
46
47 @implementation WOHTTPURLHandle
48
49 + (BOOL)canInitWithURL:(NSURL *)_url {
50   return [[_url scheme] isEqualToString:@"http"];
51 }
52
53 - (id)initWithURL:(NSURL *)_url cached:(BOOL)_flag {
54   if (![[_url scheme] isEqualToString:@"http"]) {
55     NSLog(@"%s: invalid URL scheme %@ for WOHTTPURLHandle !",
56           __PRETTY_FUNCTION__, [_url scheme]);
57     RELEASE(self);
58     return nil;
59   }
60   
61   self->shallCache = _flag;
62   self->url        = [_url copy];
63   self->status     = NSURLHandleNotLoaded;
64   return self;
65 }
66 - (void)dealloc {
67   RELEASE(self->cachedResponse);
68   RELEASE(self->url);
69   [super dealloc];
70 }
71
72 - (WOResponse *)_fetchURL:(NSURL *)_url {
73   WOHTTPConnection *connection;
74   WORequest        *request;
75   WOResponse       *response = nil;
76   
77   connection = [[WOHTTPConnection alloc] initWithHost:[_url host]
78                                          onPort:[[_url port] intValue]];
79   if (connection == nil) {
80     self->status = NSURLHandleLoadFailed;
81     return nil;
82   }
83
84   request = [[WORequest alloc] initWithMethod:@"GET"
85                                uri:[_url path]
86                                httpVersion:@"HTTP/1.0"
87                                headers:nil
88                                content:nil
89                                userInfo:nil];
90   if (request == nil) {
91     RELEASE(connection);
92     self->status = NSURLHandleLoadFailed;
93     return nil;
94   }
95   
96   if ([connection sendRequest:request]) {
97     if ((response = [connection readResponse])) {
98       if (self->shallCache)
99         ASSIGN(self->cachedResponse, response);
100       self->status = NSURLHandleLoadSucceeded;
101       RETAIN(response);
102     }
103     else
104       self->status = NSURLHandleLoadFailed;
105   }
106   else {
107     self->status = NSURLHandleLoadFailed;
108   }
109   
110   RELEASE(request);
111   RELEASE(connection);
112   
113   return AUTORELEASE(response);
114 }
115
116 - (NSData *)loadInForeground {
117   WOResponse *response;
118   NSData     *data;
119   
120   response = [self _fetchURL:self->url];
121   data = [response content];
122   RETAIN(data);
123   return AUTORELEASE(data);
124 }
125 - (void)loadInBackground {
126   [self loadInForeground];
127 }
128
129 - (void)flushCachedData {
130   RELEASE(self->cachedResponse);
131   self->cachedResponse = nil;
132 }
133
134 - (NSData *)resourceData {
135   if (self->cachedResponse) {
136     NSData *data;
137
138     data = [self->cachedResponse content];
139     RETAIN(data);
140     return AUTORELEASE(data);
141   }
142
143   return [self loadInForeground];
144 }
145 - (NSData *)availableResourceData {
146   NSData *data;
147
148   data = [self->cachedResponse content];
149   RETAIN(data);
150   return AUTORELEASE(data);
151 }
152
153 - (NSURLHandleStatus)status {
154   return self->status;
155 }
156 - (NSString *)failureReason {
157   if (self->status != NSURLHandleLoadFailed)
158     return nil;
159
160   return @"loading of HTTP URL failed";
161 }
162
163 /* properties */
164
165 - (id)propertyForKey:(NSString *)_key {
166   WOResponse *response;
167   
168   if (self->cachedResponse)
169     return [self->cachedResponse headerForKey:_key];
170   
171   response = [self _fetchURL:self->url];
172   return [response headerForKey:_key];
173 }
174 - (id)propertyForKeyIfAvailable:(NSString *)_key {
175   return [self->cachedResponse headerForKey:_key];
176 }
177
178 /* writing */
179
180 - (BOOL)writeData:(NSData *)__data {
181   WOHTTPConnection *connection;
182   WORequest        *request;
183   WOResponse       *response;
184   
185   [self flushCachedData];
186   
187   connection = [[WOHTTPConnection alloc] initWithHost:[self->url host]
188                                          onPort:[[self->url port] intValue]];
189   if (connection == nil)
190     return NO;
191   
192   request = [[WORequest alloc] initWithMethod:@"PUT"
193                                uri:[self->url path]
194                                httpVersion:@"HTTP/1.0"
195                                headers:nil
196                                content:__data
197                                userInfo:nil];
198   if (request == nil) {
199     RELEASE(connection);
200     return NO;
201   }
202   
203   if ([connection sendRequest:request])
204     response = [connection readResponse];
205   else
206     response = nil;
207   
208   if (response) {
209     if ([response status] != 200)
210       response = nil;
211   }
212   
213   RELEASE(request);
214   RELEASE(connection);
215   
216   return response ? YES : NO;
217 }
218
219 @end /* WOHTTPURLHandle */