2 Copyright (C) 2000-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
24 @interface WOFileUpload : WOInput
26 // WODynamicElement: extraAttributes
27 // WODynamicElement: otherTagString
30 // inherited: disabled
32 WOAssociation *filePath; // disposition 'filename'
33 WOAssociation *data; // uploaded data
36 @end /* WOFileUpload */
39 #include <NGMime/NGMime.h>
40 #include <NGHttp/NGHttp.h>
42 @interface WORequest(UsedPrivates)
46 @implementation WOFileUpload
48 static NGMimeType *multipartFormData = nil;
51 static BOOL isInitialized = NO;
52 if (isInitialized) return;
55 multipartFormData = [[NGMimeType mimeType:@"multipart/form-data"] retain];
58 - (id)initWithName:(NSString *)_name
59 associations:(NSDictionary *)_config
60 template:(WOElement *)_t
63 if ((self = [super initWithName:_name associations:_config template:_t])) {
64 self->filePath = OWGetProperty(_config, @"filePath");
65 self->data = OWGetProperty(_config, @"data");
71 [self->filePath release];
76 /* handling requests */
78 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
79 NGMimeMultipartBody *body;
80 NGMimeType *contentType;
86 if ([self->disabled boolValueInComponent:[_ctx component]])
89 currentId = OWFormElementName(self, _ctx);
91 if ((formValue = [_rq formValueForKey:currentId]) == nil)
94 contentType = [[_rq httpRequest] contentType];
96 if (![contentType hasSameType:multipartFormData]) {
98 @"Tried to apply file-upload value of eid=%@ from "
99 @"a non multipart-form request (value=%@).",
100 [_ctx elementID], formValue];
105 NSLog(@"%@: value=%@ ..", [self elementID], formValue);
108 if ([self->data isValueSettable])
109 [self->data setValue:formValue inComponent:[_ctx component]];
111 /* the remainder is for locating the file path */
113 if (![self->filePath isValueSettable])
116 body = [[_rq httpRequest] body];
117 if (![body isKindOfClass:[NGMimeMultipartBody class]])
118 /* TODO: shouldn't we log something? */
121 /* search for part of current form element */
123 parts = [body parts];
124 for (i = 0, count = [parts count]; i < count; i++) {
125 static Class DispClass = Nil;
128 id<NGMimePart> bodyPart;
130 bodyPart = [parts objectAtIndex:i];
131 disposition = [[bodyPart valuesOfHeaderFieldWithName:
132 @"content-disposition"] nextObject];
134 if (disposition == nil)
137 if (DispClass == Nil)
138 DispClass = [NGMimeContentDispositionHeaderField class];
140 if (![disposition isKindOfClass:DispClass]) {
142 [[DispClass alloc] initWithString:[disposition stringValue]];
143 disposition = [disposition autorelease];
146 formName = [(NGMimeContentDispositionHeaderField *)disposition name];
148 if ([formName isEqualToString:currentId]) {
149 [self->filePath setValue:[disposition filename]
150 inComponent:[_ctx component]];
156 /* generating response */
158 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
161 if ([_ctx isRenderingDisabled] || [[_ctx request] isFromClientComponent])
164 v = [self->value stringValueInComponent:[_ctx component]];
166 WOResponse_AddCString(_response, "<input type=\"file\" name=\"");
167 [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
168 WOResponse_AddChar(_response, '"');
170 WOResponse_AddCString(_response, " value=\"");
171 [_response appendContentHTMLAttributeValue:v];
172 WOResponse_AddChar(_response, '"');
174 [self appendExtraAttributesToResponse:_response inContext:_ctx];
176 if (self->otherTagString) {
177 WOResponse_AddChar(_response, ' ');
178 WOResponse_AddString(_response,
179 [self->otherTagString stringValueInComponent:
182 WOResponse_AddEmptyCloseParens(_response, _ctx);
187 - (NSString *)associationDescription {
188 NSMutableString *str;
190 str = [NSMutableString stringWithCapacity:32];
191 [str appendString:[super associationDescription]];
193 if (self->filePath != nil) [str appendFormat:@" path=%@", self->filePath];
194 if (self->data != nil) [str appendFormat:@" data=%@", self->data];
199 @end /* WOFileUpload */