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; // dispostion '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]) {
97 NSLog(@"WARNING: tried to apply file-upload value of %@ from "
98 @"a non multipart-form request (value=%@) !",
99 [_ctx elementID], formValue);
104 NSLog(@"%@: value=%@ ..", [self elementID], formValue);
107 if ([self->data isValueSettable])
108 [self->data setValue:formValue inComponent:[_ctx component]];
110 if (![self->filePath isValueSettable])
113 body = [[_rq httpRequest] body];
114 if (![body isKindOfClass:[NGMimeMultipartBody class]])
115 /* TODO: shouldn't we log something? */
118 /* search for part of current form element */
120 parts = [body parts];
121 for (i = 0, count = [parts count]; i < count; i++) {
122 static Class DispClass = Nil;
125 id<NGMimePart> bodyPart;
127 bodyPart = [parts objectAtIndex:i];
128 disposition = [[bodyPart valuesOfHeaderFieldWithName:
129 @"content-disposition"] nextObject];
131 if (disposition == nil)
134 if (DispClass == Nil)
135 DispClass = [NGMimeContentDispositionHeaderField class];
137 if (![disposition isKindOfClass:DispClass]) {
139 [[DispClass alloc] initWithString:[disposition stringValue]];
140 disposition = [disposition autorelease];
143 formName = [(NGMimeContentDispositionHeaderField *)disposition name];
145 if ([formName isEqualToString:currentId]) {
146 [self->filePath setValue:[disposition filename]
147 inComponent:[_ctx component]];
153 /* generating response */
155 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
158 if ([[_ctx request] isFromClientComponent])
161 v = [self->value stringValueInComponent:[_ctx component]];
163 WOResponse_AddCString(_response, "<input type=\"file\" name=\"");
164 [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
165 WOResponse_AddChar(_response, '"');
167 WOResponse_AddCString(_response, " value=\"");
168 [_response appendContentHTMLAttributeValue:v];
169 WOResponse_AddChar(_response, '"');
171 [self appendExtraAttributesToResponse:_response inContext:_ctx];
173 if (self->otherTagString) {
174 WOResponse_AddChar(_response, ' ');
175 WOResponse_AddString(_response,
176 [self->otherTagString stringValueInComponent:
179 WOResponse_AddEmptyCloseParens(_response, _ctx);
184 - (NSString *)associationDescription {
185 NSMutableString *str;
187 str = [NSMutableString stringWithCapacity:32];
188 [str appendString:[super associationDescription]];
190 if (self->filePath != nil) [str appendFormat:@" path=%@", self->filePath];
191 if (self->data != nil) [str appendFormat:@" data=%@", self->data];
196 @end /* WOFileUpload */