]> err.no Git - sope/blob - sope-appserver/SoOFS/OFSFileRenderer.m
Add libxml2-dev to libsope-xml4.7-dev deps
[sope] / sope-appserver / SoOFS / OFSFileRenderer.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 "OFSFileRenderer.h"
23 #include "OFSFile.h"
24 #include <NGObjWeb/WORequest.h>
25 #include <NGObjWeb/WOResponse.h>
26 #include <NGObjWeb/WOContext.h>
27 #include "common.h"
28
29 @interface OFSFile(Render)
30
31 - (id)davContentLength;
32 - (NSDate *)davLastModified;
33
34 @end
35
36 @implementation OFSFileRenderer
37
38 static NSTimeZone *gmt = nil;
39
40 + (void)initialize {
41   gmt = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain];
42 }
43
44 + (id)sharedRenderer {
45   static OFSFileRenderer *singleton = nil;
46   if (singleton == nil)
47     singleton = [[OFSFileRenderer alloc] init];
48   return singleton;
49 }
50
51 /* rendering */
52
53 - (NSException *)renderHeadOfObject:(id)_object inContext:(WOContext *)_ctx {
54   WOResponse *r;
55   id tmp;
56   
57   r = [_ctx response];
58   
59   /* render headers */
60   
61   if ((tmp = [_object contentTypeInContext:_ctx]))
62     [r setHeader:tmp forKey:@"content-type"];
63   if ((tmp = [_object davContentLength]))
64     [r setHeader:tmp forKey:@"content-length"];
65   
66   if ((tmp = [_object davLastModified])) {
67     NSCalendarDate *date;
68
69 #if COCOA_Foundation_LIBRARY
70     date = [[NSCalendarDate alloc] initWithTimeIntervalSinceReferenceDate:
71                                      [tmp timeIntervalSinceReferenceDate]];
72 #else
73     date = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
74                                      [tmp timeIntervalSince1970]];
75 #endif
76     [date setTimeZone:gmt];
77     
78     // "Tue, 10 Jul 2001 14:09:06 GMT"
79     tmp = [date descriptionWithCalendarFormat:@"%a, %d %b %Y %H:%M:%S GMT"];
80     [date release];
81     [r setHeader:tmp forKey:@"last-modified"];
82   }
83   
84   return nil;
85 }
86
87 - (NSException *)renderBodyOfObject:(id)_object inContext:(WOContext *)_ctx {
88   WOResponse *r;
89   NSData     *content;
90   NSString   *storePath;
91   id fm;
92   
93   fm        = [_object fileManager];
94   storePath = [_object storagePath];
95   content   = [fm contentsAtPath:storePath];
96   
97   /* some error handling */
98   
99   if (content == nil) {
100     // TODO: should render exception ?
101     if ([fm respondsToSelector:@selector(lastException)])
102       return (id)[fm lastException];
103     return [NSException exceptionWithHTTPStatus:404 /* not found */];
104   }
105   
106   /* render body */
107   r = [_ctx response];
108   [r setContent:content];
109   return nil;
110 }
111
112 - (NSException *)renderObject:(id)_object inContext:(WOContext *)_ctx {
113   NSException *e;
114   
115   if ((e = [self renderHeadOfObject:_object inContext:_ctx]))
116     return e;
117   
118   if (![[[_ctx request] method] isEqualToString:@"HEAD"]) {
119     if ((e = [self renderBodyOfObject:_object inContext:_ctx]))
120       return e;
121   }
122   return nil;
123 }
124
125 - (BOOL)canRenderObject:(id)_object inContext:(WOContext *)_ctx {
126   return [_object isKindOfClass:[OFSFile class]];
127 }
128
129 @end /* OFSFileRenderer */